简单的 defer 也有可能写出BUG

张开发
2026/5/5 14:10:07 15 分钟阅读

分享文章

简单的 defer 也有可能写出BUG
defer 也要小心使用带来的bugdefer 很简单但也不免大意忘记写出BUG下面这4种情况需要注意。1、defer 参数是“立即求值”func main() { i : 1 defer fmt.Println(i) // 函数运行最后输出i的值 i 2 }输出1, 原因是defer方法的参数是实时计算2、方法接收者拷贝type Car struct { name string } func (c Car) Print() { fmt.Println(c.name) } func main() { c : Car{name: Mary} defer c.Print() // 最后再调用Print输出 c.name Tom }输出的并不是Tom因为即使调用方法是接收器但它前面的值也会被立即计算所有defer处就拷贝了c与第1点原理一样。3、误认为是作用域名结束执行for i : 0; i 5000; i { f, _ : os.Open(fmt.Sprintf(file_%d.csv, i)) defer f.Close() }所有 Close() 都在函数结束才执行可能造成资源浪费或文件句柄可能被耗尽。4、未注意defer执行顺序defer fmt.Println(A) defer fmt.Println(B) defer fmt.Println(C)输出的是C、B、Adefer是一个栈先入后出。

更多文章