Skip to content

最佳实践

字数
522 字
阅读时间
3 分钟

GoRoutine 生命周期

  • Goroutine 生命周期:明确 Goroutine 退出条件,使用 context.Context 管理取消信号。避免因阻塞通道导致泄漏或数据竞争。
    go
    func (w *Worker) Run(ctx context.Context) error {
        var wg sync.WaitGroup
        go func() {
            defer wg.Done()
            process(ctx, item) // 随 ctx 取消而终止
        }()
        wg.Wait()
    }

Contexts 使用

  • 显式传递context.Context 用于传递安全凭证、追踪信息、截止时间和取消信号,应作为函数的第一个参数,贯穿调用链(从 RPC/HTTP 入口到下游请求)。
    go
    func F(ctx context.Context, otherArgs ...) {}
  • 避免结构体嵌入:不在结构体中包含 Context 字段,而是作为方法参数传递(除非必须实现第三方接口)。
  • 不可变性Context 一旦创建不可修改,可安全传递给多个调用。

复制(Copying)

  • 避免别名问题:复制其他包的结构体时(如 bytes.Buffer),注意切片引用,复制后可能共享底层数组。
  • 指针接收者:若方法接收者是指针类型(如 *T),避免复制值类型 T

加密随机数(Crypto Rand)

  • 禁止使用 math/rand:其默认种子熵不足,无法生成安全随机数(如密钥)。
  • 推荐 crypto/rand:使用 rand.Read() 生成加密安全的随机字节,按需编码为十六进制或 Base64。
    go
    func Key() string {
        buf := make([]byte, 16)
        rand.Read(buf) // 安全的随机数生成
        return fmt.Sprintf("%x", buf)
    }

空切片声明

  • 首选 nil 切片
    go
    var t []string // nil 切片,len 和 cap 均为 0
    而非 t := []string{}(非 nil 但零长度)。
  • 特殊场景:JSON 编码时,nil 切片编码为 null,非 nil 零长度切片编码为 [],按需选择。

下划线空标识符的使用

  • 暂时debug 的原因保留不使用的变量。
go
var _ = fmt.Printf
  • 接口实现检查
go
var _ io.Reader = (*MyReader)(nil)

贡献者

页面历史


总访问量 次, 访客数 人次