请问大家 go 这个 defer 这里好像错了,是我的问题还是讲义错了?

2018-03-15 16:59:27 +08:00
 mmnnyycc

https://songjiayang.gitbooks.io/go-basic-courses/content/ch6/error.html

本文档第二个例子,我试了一下,结果是 2,不是 4。本人版本go version go1.9.2 darwin/amd64

package main

import (
	"fmt"
)

func testDefer() (i int) {
	defer func() {
		fmt.Println(i)
		i = 4
	}()

	return 2
}

func main() {
	testDefer()
}

2841 次点击
所在节点    程序员
18 条回复
happywowwow
2018-03-15 17:05:24 +08:00
你要输出 testDefer() 的返回值...
mmnnyycc
2018-03-15 17:11:20 +08:00
@happywowwow 是的,谢谢
kuaner
2018-03-15 17:11:33 +08:00
func main() {
fmt.Println(testDefer())
}
ylcc
2018-03-15 17:11:42 +08:00
2 是 fmt.Println(i)的值...
BBCCBB
2018-03-15 17:18:01 +08:00
楼上老哥说的对

fmt.Println(testDefer())
TanLian
2018-03-15 17:19:14 +08:00
看来你对 golang 的 return 没理解,golang 和 C、C++不同,golang 的 return 不是一个原子语句,在你这个例子中,
把 return 2 分成了两步,第一步是 i=2,第二步是 return i (注意是字母 i )。但由于 defer 的特性(这个不了解的话我也无能为力了),defer 是插在这两步中间的,所以实际上的执行过程是这样的,
func testDefer() (i int) {
i = 2

func() {
fmt.Println(i)
i = 4
}()

return i
}
所以会打印 2,testDefer 函数的返回值是 4,明白?
实际上这个题主要考察的是 return 和 defer,理解了这两个知识点,就不难理解为什么输出为 2 了。
另可关注我的公众号“大后端开发”,讲解了 golang 的很多这方面的知识。
mmnnyycc
2018-03-15 17:23:21 +08:00
@TanLian 明白,defer 在 return 之后执行
hawken
2018-03-15 20:34:21 +08:00
@TanLian 没搜到“大后端开发”这个公众号啊
TanLian
2018-03-15 20:47:31 +08:00
wweir
2018-03-16 06:31:00 +08:00
把 print 放到 main 里就是 4 了
archliinux
2018-03-16 10:53:45 +08:00
@TanLian 这种水平就不要出来开公众号误导人了

A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns.
TanLian
2018-03-16 14:46:14 +08:00
@archliinux 不想和你争辩,公众号怎么你了?你牛逼怎么不见你分析,就在这喷别人
TanLian
2018-03-16 14:48:38 +08:00
@archliinux 公众号的每篇文章都是一个字一个字的码出来的好吗,如果你觉得某个知识点有错误,可以提出来我确定后会改。但是如果你看都没看的话就这这 BB,那么就恕不奉陪了。
nekoyaki
2018-03-16 17:54:47 +08:00
@TanLian
第一,谁管你是不是一个字一个字码出来的,错了就是错了。
第二,他扔出官方解释的原文来了,事实是他扔的原文是对的,你的理解完全是强行解释,理解错误。
nekoyaki
2018-03-16 17:56:37 +08:00
@TanLian
其实你的解释如果把什么“原子不原子”、“插在两步之间”去掉,也没什么问题,就怕画蛇添足……
TanLian
2018-03-16 18:05:45 +08:00
@nekoyaki 看来你对 return 不理解,golang 的 return 本来就不是一个原子语句,这样解释没毛病,并且更利于他人理解,其他不想多说。
nekoyaki
2018-03-16 18:19:05 +08:00
@TanLian
看来你比 golang 官方文档更理解 golang。不愧是大牛,失敬失敬。
TanLian
2018-03-16 18:45:55 +08:00
@nekoyaki 呵呵,也许我的表达有问题吧。不过你可以参考这几篇文章,应该就能理解我说的了。
https://studygolang.com/articles/7548
https://www.golangtc.com/t/56667d4db09ecc6de0000025
https://tiancaiamao.gitbooks.io/go-internals/content/zh/03.4.html
http://blog.csdn.net/hittata/article/details/77836435
我不敢保证这几篇文章的内容有价值,仅作参考,当然你也可以忽略。
另祝君安好。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/438384

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX