go 匿名函数

发布于 2022-09-12 00:40:30 字数 346 浏览 16 评论 0

刚开始学习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哪
哪位大神能从原理上给解答一下,非常感谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝色星空 2022-09-19 00:40:30

上面的可以转换成这样:

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这个内存从栈上分配到堆上了

日久见人心 2022-09-19 00:40:30

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

执手闯天涯 2022-09-19 00:40:30

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

护你周全 2022-09-19 00:40:30

内存逃逸,你可以在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())  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文