关于函数闭包的疑问

Question:

  • 为何输出都为4,不应该是0,1,2,3吗,每次执行的4是怎么来的呢
  • [4]func(){},数组中的4是指 4个匿名函数吗
  • fs[i] = func() {fmt.Println("打印i = ", i)} 这句赋值会执行打印吗
  • [4]func(){} 中的数值该大或者改小为什么会出现问题呢,小则都不执行报 goroutine ,增大则会执行且报 goroutine
  • [4]func(){} 为什么不能定义成一个 slice

Code:

package main
import "fmt"
func main() {
    var fs [4]func()
    {
    }
    for i := 0; i < 4; i++ {
        fs[i] = func() {
            fmt.Println("打印i = ", i)
        }
    }

    for _, f := range fs {
        f()
    }
}

Outpit:
打印i =  4
打印i =  4
打印i =  4
打印i =  4

进程 已完成,退出代码为 0

望指点

Mericustar
最佳答案

闭包捕获的是你外部 for 里面的局部变量 i,i 迭代4次之后值为4,然后执行闭包就输出 i,也就是 4

2周前 评论
Mericustar (作者) 2周前
Scrooge (楼主) 2周前
Mericustar (作者) 2周前
Scrooge (楼主) 2周前
讨论数量: 8
Mericustar

闭包捕获的是你外部 for 里面的局部变量 i,i 迭代4次之后值为4,然后执行闭包就输出 i,也就是 4

2周前 评论
Mericustar (作者) 2周前
Scrooge (楼主) 2周前
Mericustar (作者) 2周前
Scrooge (楼主) 2周前

for 是先执行完 i = 4 没问题 ,main() 中 for i是一个内存地址 ,不是4个内存地址,for完 在取到的内存中i是4了,

改成func(i int) 传给进去了 func(i int)中i会在栈开辟新的空间 i就是4份内存空间了 打印出来就会是 0,1,2,3

2周前 评论

喔,这种打印的话,是打印的最后的全局变量的i,就是最后结束的i值,要打印0到3得用闭包

2周前 评论

变量作用域和函数调用环境的问题,换成下面这个才是你要的

        fs[i] = (func(i int) func() {
            return func() {
                fmt.Println("打印i = ", i)
            }
        })(i)
2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!