MST

星途 面试题库

面试题:Go中闭包使用时因变量作用域导致的常见错误及规避方法

在Go语言中,假设有如下代码: ```go package main import ( "fmt" ) func main() { var funcs []func() for i := 0; i < 3; i++ { funcs = append(funcs, func() { fmt.Println(i) }) } for _, f := range funcs { f() } } ``` 这段代码输出的结果是什么?为什么会出现这样的结果?如何修改代码来实现预期输出(分别输出0, 1, 2)?
49.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 输出结果: 输出结果为:
    3
    3
    3
    
  2. 原因: 在Go语言中,for循环中的i是一个变量,而不是每次迭代都创建一个新的变量。在闭包中,fmt.Println(i)引用的是同一个i变量。当for循环结束后,i的值为3。所以当调用闭包函数时,打印的都是循环结束后i最终的值3
  3. 修改代码实现预期输出: 方法一:使用一个新的变量捕获i的值
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var funcs []func()
        for i := 0; i < 3; i++ {
            j := i
            funcs = append(funcs, func() {
                fmt.Println(j)
            })
        }
        for _, f := range funcs {
            f()
        }
    }
    
    方法二:将i作为参数传递给闭包函数
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var funcs []func()
        for i := 0; i < 3; i++ {
            funcs = append(funcs, func(n int) func() {
                return func() {
                    fmt.Println(n)
                }
            }(i))
        }
        for _, f := range funcs {
            f()
        }
    }