golang Go 闭包与循环变量陷阱及解决方案
示例 1:未处理的闭包变量陷阱
func main() {
    for i := 0; i < 3; i++ {
        defer func() { println(i) }()
    }
}
现象
输出:3 3 3(三个 3)
原因
- 闭包捕获的是变量的引用,而非值。
 - 循环结束后,
i的最终值为3,所有defer的匿名函数捕获的都是同一个外部变量i,因此打印的都是3。 
示例 2:通过局部变量解决陷阱
func main() {
    for i := 0; i < 3; i++ {
        i := i // 定义循环体内局部变量 i
        defer func() { println(i) }()
    }
}
现象
输出:0 1 2(按逆序打印)
原因
- 在循环体内重新定义局部变量 
i,每次循环迭代都会创建一个新的局部变量i。 - 闭包捕获的是该局部变量 
i的值(当前循环的i),因此每个defer函数捕获的变量是独立的。 
示例 3:通过参数传递解决陷阱
func main() {
    for i := 0; i < 3; i++ {
        defer func(i int) { println(i) }(i) // 立即传递当前 i 的值
    }
}
现象
输出:0 1 2(按逆序打印)
原因
- 在 
defer中定义匿名函数时,将当前i的值作为参数传递。 - 参数 
i在defer声明时立即求值,因此每个匿名函数捕获的是循环当前迭代的i的值。 
                    
                
                
                
            
        
浙公网安备 33010602011771号