go 匿名函数

manbudezhu
  • 229

刚开始学习go语言,在做匿名函数的例子,遇到一些问题

func intSeq() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}
func main() {

    nextInt := intSeq()

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())
}

上面的代码执行的结果是 1 2 3
为什么结果不是1 1 1哪
哪位大神能从原理上给解答一下,非常感谢

回复
阅读 1.3k
4 个回答

上面的可以转换成这样:

func main() {
    // nextInt := intSeq()
    i := 0

    nextInt := func() int {
        i++
        fmt.Printf("%#+v \n", &i)
        return i
    }

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())
}

输出:

(*int)(0xc000014098) 
1
(*int)(0xc000014098) 
2
(*int)(0xc000014098) 
3

内部声明的变量return func() 变量没在一个func内应用回收掉, 就产生内存逃逸了, 把i这个内存从栈上分配到堆上了

这就是闭包,i是在匿名函数外层定义的,这个i是公用的

那个i指向的是同一个内存地址

南岛的森林
  • 1
新手上路,请多包涵

内存逃逸,你可以在return func()里面打印,i都是同一个地址,后面的i自增都是对同一地址i操作。
除非改成这样:

func intSeq() func() int {  
   i := 0  
  return func() int {  
      i++  
      return i  
   }  
}  
func main() {  
  
   nextInt := intSeq()  
  
   fmt.Println(nextInt())  
   nextInt = intSeq()  
  
   fmt.Println(nextInt())  
   nextInt = intSeq()  
  
   fmt.Println(nextInt())  
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏