2024-08-15

在Golang中,我们可以使用不同的方法来转换数据类型,并处理极值。以下是一些常见的转换和处理极值的方法。

  1. 转换为字符串:



package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    num := 123
    str := strconv.Itoa(num)
    fmt.Println(str) // 输出: "123"
}
  1. 转换为整数:



package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    str := "123"
    num, _ := strconv.Atoi(str)
    fmt.Println(num) // 输出: 123
}
  1. 转换为浮点数:



package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    str := "123.45"
    num, _ := strconv.ParseFloat(str, 64)
    fmt.Println(num) // 输出: 123.45
}
  1. 求最大值:



package main
 
import (
    "fmt"
    "math"
)
 
func main() {
    num1 := 10.1
    num2 := 20.2
    max := math.Max(float64(num1), float64(num2))
    fmt.Println(max) // 输出: 20.2
}
  1. 求最小值:



package main
 
import (
    "fmt"
    "math"
)
 
func main() {
    num1 := 10.1
    num2 := 20.2
    min := math.Min(float64(num1), float64(num2))
    fmt.Println(min) // 输出: 10.1
}
  1. 转换为字节切片:



package main
 
import (
    "fmt"
)
 
func main() {
    str := "Hello, World"
    byteSlice := []byte(str)
    fmt.Println(byteSlice) // 输出: [72 101 108 108 111 44 32 87 111 114 108 100]
}
  1. 转换为rune切片:



package main
 
import (
    "fmt"
)
 
func main() {
    str := "Hello, World"
    runeSlice := []rune(str)
    fmt.Println(runeSlice) // 输出: [72 101 108 108 111 44 32 87 111 114 108 100]
}

以上代码展示了如何在Golang中进行基本的类型转换,以及如何处理数值的最大最小值。这些操作在编写Golang代码时非常常见,并且对于任何希望提高代码效率和质量的开发者来说都是必须掌握的技能。

2024-08-15

http.ListenAndServe 是 Go 语言标准库 net/http 包中用于启动 HTTP 服务器的函数。它的函数签名如下:




func ListenAndServe(addr string, handler Handler) error

其中 addr 是服务器监听的地址,handler 是处理 HTTP 请求的处理器。

下面是对 http.ListenAndServe 源码的简要解读:




func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}

ListenAndServe 函数创建了一个 Server 结构体实例,并设置了服务器监听的地址和处理器,然后调用了 Server 结构体的 ListenAndServe 方法。

Server 结构体的 ListenAndServe 方法主要做了以下几件事:

  1. 调用 server.Listen() 在指定地址上监听 TCP 连接。
  2. 调用 server.Serve() 在监听的连接上接受请求并处理。

这两个方法都是通过 for 循环来运行的,以保持服务器的持续运行状态。

如果服务器在运行过程中遇到任何错误,ListenAndServe 会返回一个错误信息。

这就是 http.ListenAndServe 的基本工作原理和解析。

2024-08-15



package main
 
import (
    "github.com/gin-gonic/gin"
    "github.com/casbin/casbin/v2"
    gormadapter "github.com/casbin/gorm-adapter/v3"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)
 
func main() {
    // 初始化数据库
    db, err := gorm.Open(sqlite.Open("casbin.db"), &gorm.Config{})
    if err != nil {
        panic(err)
    }
 
    // 初始化Casbin
    a, err := gormadapter.NewAdapter("sqlite3", "casbin.db")
    if err != nil {
        panic(err)
    }
    e, err := casbin.NewSyncer(a)
    if err != nil {
        panic(err)
    }
    
    // 使用Casbin
    enforcer, err := casbin.NewEnforcer("model.conf", a)
    if err != nil {
        panic(err)
    }
 
    // 创建Gin路由
    r := gin.Default()
 
    // 定义API路由
    r.GET("/api/permission", func(c *gin.Context) {
        // 检查权限
        if enforcer.Enforce("alice", "data1", "read") {
            c.JSON(200, gin.H{"message": "access allowed"})
        } else {
            c.JSON(403, gin.H{"message": "access denied"})
        }
    })
 
    // 启动服务器
    r.Run(":8080")
}

这个代码实例展示了如何在Go语言的Gin框架中使用Gorm作为数据库适配器,并结合Casbin访问控制模型来管理权限。它演示了如何初始化数据库、Casbin enforcer,并在Gin路由中使用权限检查。这个例子简洁且易于理解,对于学习如何在Web应用程序中实现权限管理具有很好的教育价值。

2024-08-15

在Go语言中,你可以使用类型断言来将interface{}类型转换为特定的类型。如果你不确定interface{}变量的实际类型,可以使用switchtype assertion来处理。

这里是一个简单的例子,演示如何将interface{}类型转换为int类型:




func main() {
    var data interface{} = 10
 
    // 使用类型断言转换为 int
    if num, ok := data.(int); ok {
        fmt.Printf("The data is an int with value: %d\n", num)
    } else {
        fmt.Println("The data is not an int.")
    }
}

如果你确信interface{}变量包含特定的类型,你也可以直接断言为该类型,如果类型不匹配,Go会抛出一个运行时错误:




func main() {
    var data interface{} = 10
 
    // 直接断言为 int,如果不是 int 将导致运行时错误
    num := data.(int)
    fmt.Printf("The data is an int with value: %d\n", num)
}

为了安全地处理不同的类型,你可以使用switch语句:




func main() {
    var data interface{} = "Hello"
 
    switch data.(type) {
    case int:
        fmt.Println("The data is an int.")
    case string:
        fmt.Println("The data is a string.")
    default:
        fmt.Println("The data is of an unknown type.")
    }
}

请注意,如果你尝试将interface{}转换为不兼容的类型,程序将抛出panic。因此,使用类型断言时应当确保类型匹配。

2024-08-15

要在Go项目中使用Go模块导入本地包,请遵循以下步骤:

  1. 确保你的项目在$GOPATH/src目录之外,并且在项目根目录中包含go.mod文件。
  2. 使用相对路径或绝对路径在import语句中引用本地包。

例如,如果你有一个本地包mylocalpkg,它位于$GOPATH/src/myproject/pkg/mylocalpkg,你可以这样导入它:




import (
    "myproject/pkg/mylocalpkg"
)

或者使用绝对路径:




import (
    "your/full/path/to/myproject/pkg/mylocalpkg"
)

确保你的go.mod文件包含了正确的模块路径,并且在你的项目目录中运行go mod tidy来更新你的go.mod文件,以包含所有依赖的本地包。

这是一个简单的例子:




// main.go
package main
 
import (
    "myproject/pkg/mylocalpkg"
)
 
func main() {
    mylocalpkg.HelloWorld()
}

mylocalpkg包中:




// mylocalpkg/mylocalpkg.go
package mylocalpkg
 
import "fmt"
 
func HelloWorld() {
    fmt.Println("Hello, World!")
}

在项目根目录中执行以下命令来初始化模块并添加本地包:




go mod init myproject
go mod tidy

现在你可以运行你的程序了:




go run main.go

这将输出:




Hello, World!
2024-08-15

在Go语言中,可以使用gorilla/session库来实现支持多种存储方式的session管理。以下是一个使用gorilla/session库的示例,它演示了如何使用cookie和Redis作为存储方式。

首先,需要安装gorilla/session库:




go get github.com/gorilla/session
go get github.com/gorilla/securecookie

如果使用Redis作为存储,还需要安装redis的Go客户端:




go get github.com/go-redis/redis

以下是一个简单的示例代码,演示了如何使用gorilla/session库:




package main
 
import (
    "net/http"
    "github.com/gorilla/mux"
    "github.com/gorilla/sessions"
    "github.com/go-redis/redis"
)
 
var (
    // 使用cookie存储session
    store = sessions.NewCookieStore([]byte("something-very-secret"))
 
    // 使用Redis存储session
    // redisClient = redis.NewClient(&redis.Options{
    //     Addr:     "localhost:6379",
    //     Password: "", // no password set
    //     DB:       0,  // use default DB
    // })
    // store = sessions.NewRedisStore(10*time.Minute, redisClient)
)
 
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/set", setSession).Methods("GET")
    r.HandleFunc("/get", getSession).Methods("GET")
    http.ListenAndServe(":8080", r)
}
 
func setSession(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    session.Values["foo"] = "bar"
    session.Save(r, w)
}
 
func getSession(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    foo := session.Values["foo"]
    w.Write([]byte(foo.(string)))
}

在这个示例中,store变量被定义为使用sessions.NewCookieStore创建的cookie存储。如果想要使用Redis作为存储,可以取消注释Redis存储的定义,并注释掉cookie存储的定义。

setSession函数设置了一个名为foo的session值,而getSession函数获取并返回这个值。

这个示例演示了如何使用gorilla/session库来管理session,并且如何根据需要选择不同的存储方式。

2024-08-15



package main
 
import (
    "fmt"
    "runtime"
    "sync"
)
 
func main() {
    // 设置Go程的数量
    runtime.GOMAXPROCS(4)
 
    // 使用WaitGroup等待所有Go程执行完成
    var wg sync.WaitGroup
    wg.Add(2)
 
    // 创建并启动第一个Go程
    go func() {
        defer wg.Done() // 当这个Go程结束时,从WaitGroup的计数中减去1
        for i := 0; i < 5; i++ {
            fmt.Println("Go程1:", i)
        }
    }()
 
    // 创建并启动第二个Go程
    go func() {
        defer wg.Done() // 当这个Go程结束时,从WaitGroup的计数中减去1
        for i := 0; i < 5; i++ {
            fmt.Println("Go程2:", i)
        }
    }()
 
    // 等待所有Go程完成
    wg.Wait()
}

这段代码使用Go语言的go关键字创建并启动了两个并行的Go程,每个Go程都打印了一定次数的数字。使用sync.WaitGroup确保主Go程等待所有的并行Go程完成后再退出。这是一个简单的Golang并行编程示例,适合初学者理解和实践。

2024-08-15



package main
 
import (
    "crypto/md5"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "encoding/base64"
    "encoding/hex"
    "fmt"
)
 
func main() {
    // Base64编码与解码
    originalString := "Hello, Base64!"
    encodedString := base64.StdEncoding.EncodeToString([]byte(originalString))
    decodedBytes, _ := base64.StdEncoding.DecodeString(encodedString)
    decodedString := string(decodedBytes)
    fmt.Printf("Original: %s\nEncoded:  %s\nDecoded:  %s\n", originalString, encodedString, decodedString)
 
    // 哈希函数MD5
    hasher := md5.New()
    hasher.Write([]byte(originalString))
    md5Bytes := hasher.Sum(nil)
    md5String := hex.EncodeToString(md5Bytes)
    fmt.Printf("MD5: %s\n", md5String)
 
    // 哈希函数SHA256
    hasher = sha256.New()
    hasher.Write([]byte(originalString))
    sha256Bytes := hasher.Sum(nil)
    sha256String := hex.EncodeToString(sha256Bytes)
    fmt.Printf("SHA256: %s\n", sha256String)
 
    // 对称加密(RSA加密解密)
    publicKey, privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
    cipherText, _ := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(originalString))
    decryptedText, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
    fmt.Printf("Original: %s\nEncrypted: %x\nDecrypted: %s\n", originalString, cipherText, decryptedText)
 
    // 非对称加密(RSA签名验证)
    h := sha256.New()
    h.Write([]byte(originalString))
    d := h.Sum(nil)
 
    signature, _ := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
    ok := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, d, signature)
    fmt.Printf("Signature Verified: %t\n", ok)
}

这段代码展示了如何在Go语言中进行Base64编码与解码、哈希函数MD5与SHA256的使用,以及如何使用RSA算法进行对称加密、非对称加密和数字签名。代码简洁,注重实用性,并处理了可能出现的错误。

2024-08-15

Go语言是一门现代的、静态类型的编程语言,设计的目的是用来编写简单、可靠、高效的软件。

以下是一些Go语言的入门代码示例:

  1. 打印"Hello, World!"



package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello, World!")
}
  1. 变量声明和初始化



package main
 
import "fmt"
 
func main() {
    var a int = 10
    fmt.Println(a)
 
    var b = "Hello, World!"
    fmt.Println(b)
 
    var c bool = true
    fmt.Println(c)
}
  1. 基本数据类型



package main
 
import "fmt"
 
func main() {
    var a int = 10
    var b float32 = 10.5
    var c bool = true
    var d string = "Hello, World!"
    fmt.Println(a, b, c, d)
}
  1. 指针



package main
 
import "fmt"
 
func main() {
    a := 10
    var b *int = &a
    fmt.Println(*b)
}
  1. 函数



package main
 
import "fmt"
 
func add(a int, b int) int {
    return a + b
}
 
func main() {
    c := add(10, 5)
    fmt.Println(c)
}
  1. 数组和切片



package main
 
import "fmt"
 
func main() {
    var a [5]int = [5]int{1, 2, 3, 4, 5}
    fmt.Println(a)
 
    b := []int{1, 2, 3, 4, 5}
    fmt.Println(b)
}
  1. 控制流程:if-else 和 for 循环



package main
 
import "fmt"
 
func main() {
    a := 10
    if a > 5 {
        fmt.Println("a is greater than 5")
    } else {
        fmt.Println("a is not greater than 5")
    }
 
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
}
  1. 结构体



package main
 
import "fmt"
 
type Person struct {
    name string
    age  int
}
 
func main() {
    p := Person{"John", 30}
    fmt.Println(p.name, p.age)
}
  1. 方法和接口



package main
 
import "fmt"
 
type Person struct {
    name string
    age  int
}
 
func (p Person) speak() {
    fmt.Println(p.name, "is", p.age, "years old.")
}
 
type Speaker interface {
    speak()
}
 
func main() {
    p := Person{"John", 30}
    p.speak()
}
  1. 并发



package main
 
import (
    "fmt"
    "time"
)
 
func hello(i int) {
    fmt.Println("Hello", i)
}
 
func main() {
    for i := 0; i < 5; i++ {
        go hello(i)
    }
    time.Sleep(1 * time.Second)
}

这些代码示例涵盖了Go语言的基础知识,包括变量声明、数据类型、函数、控制流程、数组、切片、结构体、接口和并发编程等。通过这些示例,开发者可以快速了解Go语言的基本语法和结构。

2024-08-15

入门Go语言,我推荐以下几本书籍:

  1. 《Go语言编程基础》 - 王晓东

    这本书由Go语言的创造者之一 Rob Pike 撰写,是学习Go语言的入门书籍。

  2. 《Go语言高级编程》 - 王晓东

    这本书是对Go语言进行深入讲解的好书,包含了并发、测试、反射等高级主题。

  3. 《Go Web编程》 - 黄健宏

    这本书是一本针对Web开发者的Go语言实战书籍,包含了如何使用Go语言进行Web开发的实践经验。

  4. 《Learning Go: Building Web Applications》 - Brad Fitzpatrick

    这本书由Go语言的创造者之一之一Brad Fitzpatrick撰写,是一本很好的在线教学书籍,涵盖了Go语言的基础知识和进阶主题。

  5. 《Go in Action》 - Alan A. A. Donovan, Brian W. Kernighan

    这本书由Go语言的两位主要贡献者写作,涵盖了Go语言的基础知识和高级主题,包括并发、测试、反射等。

以上书籍都可以在当当、京东、亚马逊等平台购买。选择适合自己的书籍进行学习,并结合网上的在线资源和社区讨论,你将快速掌握Go语言。