遇到的一些GO问题

发布于:2025-02-12 ⋅ 阅读:(164) ⋅ 点赞:(0)

1.goroutine 泄漏

// 错误示例
go func() {
    // 没有控制退出
    for {
        process()
    }
}()

// 正确示例
done := make(chan bool)
go func() {
    for {
        select {
        case <-done:
            return
        default:
            process()
        }
    }
}()

2.channel 使用

// 常见错误:向已关闭的 channel 写入数据
close(ch)
ch <- data  // panic

// 常见错误:重复关闭 channel
close(ch)
close(ch)  // panic

3.切片容量问题

// 可能导致内存泄漏
data := []string{"a", "b", "c", "d", "e"}
slice := data[2:3]  // slice 仍然引用着整个 data 底层数组

// 正确做法:使用 copy
newSlice := make([]string, 1)
copy(newSlice, data[2:3])

4.nil 切片 vs 空切片

var s1 []int         // nil 切片
s2 := []int{}       // 空切片
s3 := make([]int,0) // 空切片

// nil 切片和空切片的长度都是 0,但是 nil 切片的底层指针为 nil

5. 错误包装

// Go 1.13+ 推荐用法
if err != nil {
    return fmt.Errorf("failed to process: %w", err)
}

6. 错误判断

// 判断具体错误
if errors.Is(err, os.ErrNotExist) {
    // 处理文件不存在的情况
}

// 判断错误类型
var pathError *os.PathError
if errors.As(err, &pathError) {
    fmt.Println(pathError.Path)
}


7. 接口实现检查

var _ io.Reader = (*MyType)(nil)  // 编译时检查接口实现

8. 空接口 vs nil

var i interface{} = nil  // nil 接口
var p *int = nil
var i interface{} = p    // 非 nil 接口,包含 nil 指针

9. 并发访问

// 错误示例:并发读写 map
go func() { m["key"] = value }()
go func() { _ = m["key"] }()

// 正确示例:使用 sync.Map
var m sync.Map
m.Store("key", value)
value, ok := m.Load("key")

10. nil map

// 错误示例
var m map[string]int
m["key"] = 1  // panic

// 正确示例
m := make(map[string]int)
m["key"] = 1

11. 循环变量捕获

// 错误示例
for i := 0; i < 5; i++ {
    go func() {
        fmt.Println(i)  // 所有 goroutine 可能打印相同的值
    }()
}

// 正确示例
for i := 0; i < 5; i++ {
    i := i  // 创建新的变量
    go func() {
        fmt.Println(i)
    }()
}

12. defer 相关

// defer 的参数在声明时就已经确定
i := 0
defer fmt.Println(i)  // 将打印 0,而不是最终的值
i = 1

// 正确用法:使用闭包
defer func() { fmt.Println(i) }()

13. JSON 处理

// 常见错误:未导出字段无法序列化
type User struct {
    name string  // 小写,不会被序列化
    Age  int     // 大写,会被序列化
}

// 正确示例
type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}


网站公告

今日签到

点亮在社区的每一天
去签到