func test1() int {
var a int
defer func() {
a++
}()
return a
}
func test2() (a int) {
defer func() {
a++
}()
return a
}
test1 最终返回 0
,test2 最终返回 1
。
这种令人混淆的行为是一个语言缺陷还是一个 feature ?
今天面试碰上没答起,潜意识认为这两货没区别😥
1
reus 2019-05-14 23:27:58 +08:00
说明你不知道 defer 是在什么时机执行的,基础不牢。
面试就是要试出你的真实水平,有人连 abc 都认不全,难道是字母“令人混淆”?难道是字母有“缺陷”? |
3
FEDT 2019-05-14 23:40:23 +08:00 via iPhone
有答案吗
|
4
zzn 2019-05-14 23:41:29 +08:00
似乎并不怎么令人混淆吧?
|
5
blless 2019-05-14 23:42:10 +08:00 via Android
你这代码有问题吧
|
6
silenceshell 2019-05-14 23:46:59 +08:00 1
defer 发生在“真正”的 retrun 之前。
|
7
Maboroshii 2019-05-14 23:51:01 +08:00
学习了。顺便翻了一下资料
https://blog.golang.org/defer-panic-and-recover > 3.Deferred functions may read and assign to the returning function's named return values. |
8
ArianX OP @silenceshell 这是作用机制层面上的吧。我想讨论的是究竟为什么要这样设计,在什么场景会用到
|
9
Zzdex 2019-05-14 23:55:25 +08:00
@ArianX #8 你看楼上的链接,This is convenient for modifying the error return value of a function;
便于修改错误的返回值 |
10
victor 2019-05-15 00:02:48 +08:00 1
|
11
ArianX OP 匿名返回值函数里的 defer 也能访问到返回值,也允许写出修改返回值的语句,为什么要设计为修改对最终返回的值无效?为什么不直接设计为不允许修改?利用到这种差异的场景是什么?
|
12
poplar50 2019-05-15 00:14:09 +08:00 via Android
学习了,七楼发的链接我看 go tour 的时候还翻过,但是竟然没注意这个。现在想想,defer 既然被设计用来做一些收尾工作,那么出现这种情况就是为了让 defer 也能够处理函数返回值吧。
|
13
ArianX OP 好吧,突然想到某些场景下可能不需要修改最终返回值,但需要在 defer 里使用返回的值做一些操作,于是允许匿名返回值里的 defer 修改返回值,就能够复用同一个变量。
|
14
ArianX OP 话说我想讨论的是为什么要特别设计出匿名返回值和命名返回值 defer 行为的差异,而不是在 defer 里修改返回值的意图
|
15
catror 2019-05-15 00:31:33 +08:00 via Android 1
你可以这么理解,返回值其实是关联有一个返回变量的,第一个例子里,因为匿名,defer 函数访问不到返回变量,而变量 a 只是局部变量,修改局部变量自然是影响不到返回变量。
|