关于golang:Go-群友提问学习-defer-时很懵逼这道不会做

10次阅读

共计 1251 个字符,预计需要花费 4 分钟才能阅读完成。

若有任何问题或倡议,欢送及时交换和碰撞。我的公众号是【脑子进煎鱼了】,GitHub 地址:https://github.com/eddycjy。

大家好,我是煎鱼。

前几天在读者交换群里看到一位小伙伴,在向大家征询 Go 相干的技术问题。
疑难是:“各位大佬,我在学习 defer 遇到闭包的时候很懵逼,谁比拟明确,能指导?

疑难

他的疑难是上面这道 Go 语言的 defer 题目,大家一起看看:

func main() {var whatever [6]struct{}
    for i := range whatever {defer func() {fmt.Println(i)
        }()}
}

请本人先想一下输入的后果答案是什么。

这位小伙伴按本人的了解后,认为该当输入 xx。但最终的输入后果,可能与其思考的有所偏差,一时想不通。

解惑

这段程序的输入后果是:

5
5
5
5
5
5

为什么全是 5,为什么不是 0, 1, 2, 3, 4, 5 这样的输入后果呢?

其根本原因是 闭包 所导致的,有两点起因:

  • for 循环完结后,局部变量 i 的值曾经是 5 了,并且 defer 的闭包是间接援用变量的 i。
  • 联合defer 关键字的个性,可得悉会在 main 办法主体完结后再执行。

联合上述,最终输入的后果是曾经自增结束的 5。

进一步思考

既然理解了为什么,咱们再变形一下。再看看另外一种状况,代码如下:

func main() {var whatever [6]struct{}
    for i := range whatever {defer func(i int) {fmt.Println(i)
        }(i)
    }
}

与第一个案例不同,咱们这回把变量 i 传了进去。那么他的输入后果是什么呢?

这段程序的输入后果是:

5
4
3
2
1
0

为什么是 5, 4, 3, 2, 1, 0 呢,为什么不是 0, 1, 2, 3, 4, 5?(难道煎鱼敲错了吗?)

其根本原因在于两点:

  • for 循环时,局部变量 i 曾经传入进 defer func 中,属于值传递。其值在 defer 语句申明时的时候就曾经确定下来了。
  • 联合 defer 关键字的个性,是按 先进后出 的程序来执行的。

联合上述,最终输入的后果是 5, 4, 3, 2, 1, 0。

下一个疑难

没过一会,这位小伙伴又有了新的感悟。抛出了新的示例问题,如下:

func f1() (r int) {defer func() {r++}()
   return 0
}

func f2() (r int) {
   t := 5
   defer func() {t = t + 5}()
   return t
}

func f3() (r int) {defer func(r int) {r = r + 5}(r)
   return 1
}

主函数:

func main() {println(f1())
    println(f2())
    println(f3())
}

请本人先想一下输入的后果答案是什么。

这段程序的输入后果是:

1
5
1

为什么是 1, 5, 1 呢,而不是 0, 10, 5,又或是其余答案?

欢送大家在 下方评论区留言探讨和分享解题的思路,一起思考和提高。

我的公众号

分享 Go 语言、微服务架构和奇怪的零碎设计,欢送大家关注我的公众号和我进行交换和沟通。

最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

正文完
 0