易犯的五个Go编码错误

1. 使用 time.Parse()解析时间

导致获取的时间戳比真实的多 8 小时。即使设置了全局的time.Local也一样,更换成time.ParseInLocation即可,原因:

go 复制代码
 
func Parse(layout, value string) (Time, error) {
	// Optimize for RFC3339 as it accounts for over half of all representations.
	if layout == RFC3339 || layout == RFC3339Nano {
		if t, ok := parseRFC3339(value, Local); ok {
			return t, nil
		}
	}
    // 源码中写死的UTC时区
	return parse(layout, value, UTC, Local)
}

2. 不清楚 defer 参数是被立即计算的

go 复制代码
 
func Doing() error {
    var err error
    defer handlerErr(err) // handlerErr 永远得到的err是nil
    err = doSomething()
    return err
}

3. 循环中 defer

go 复制代码
 
func Doing() {
	mutex := sync.Mutex{}
	for i := 0; i < 1000000000; i++ {
		mutex.Lock()
		defer mutex.Unlock() // 死锁,因为要等方法结束后才Unlock
        // do something
	}
}

4. 未注意 net/http 中 ctx 生命周期

go 复制代码
 
package main
import (
    "context"
    "net/http"
)

func main() {
    http.HandleFunc("/createOrder", func(w http.ResponseWriter, r *http.Request) {
       ctx := r.Context()
       // 创建订单
       orderDo := createOrder(ctx, reqParams)

       // 异步推送订单到供应链
       go SubmitToSupplier(ctx, orderDo)
    })
    http.ListenAndServe(":8080", nil)
}

由于 ctx 在 socket 连接读取出错或 handleFunc 完成时会被 cancel,导致:

  1. 当浏览器或调用方的 clinet 主动关闭时,即使 createOrder 未运行完,ctx 也会收到 cancel 事件,如是里面有 DB 不在一个事务、或支持 ctx 的 IO 请求的操作,都会中断。
  2. 协程启动后,由于 handleFunc 运行结束,ctx 被 cancel,导致程序受协程方法运行受影响

5. 协程中未捕获 panic

导致主程序退出,建议统一封装启动协程方法,否则很容易忘记 recover panic

相关推荐
mtngt111 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto4 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室5 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题5 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉7 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想
asaotomo8 天前
一款 AI 驱动的新一代安全运维代理 —— DeepSentry(深哨)
运维·人工智能·安全·ai·go
码界奇点8 天前
基于Gin与GORM的若依后台管理系统设计与实现
论文阅读·go·毕业设计·gin·源代码管理
迷迭香与樱花8 天前
Gin 框架
go·gin
只是懒得想了9 天前
用Go通道实现并发安全队列:从基础到最佳实践
开发语言·数据库·golang·go·并发安全