这是 Golang 中的一个函数,它使用 defer 来改变函数 c() 的命名返回值。package mainimport "fmt"func c() (i int) { defer func() { }() defer fmt.Println("our i is", i) return 45 }func main() { fmt.Println(c()) }程序的输出是:我们的 i 是 045更改代码中的匿名 func()func c() (i int) { defer func() { i = 1 }() defer fmt.Println("our i is", i) return 45 } func main() { fmt.Println(c()) }这导致输出:我们的 i 是 01如果没有其他值被放入 i 中,似乎返回值 45 会自动复制到 i 。但我不是 100% 确定这是否是输出的确切原因
1 回答
浮云间
TA贡献1829条经验 获得超4个赞
在延迟函数中,您有机会修改结果参数的值。
调用延迟函数时,return
语句中指定的值已经设置。
如果有多个延迟函数,它们会按 LIFO 顺序(后进先出)执行。
在您的第二个示例中,fmt.Println()
首先执行,然后是另一个匿名函数。
但是你需要知道的是,当defer
语句执行时,延迟函数的参数会立即计算,而不是在延迟函数运行时(稍后,在返回之前)。
每次执行“defer”语句时,函数值和调用的参数都会像往常一样评估并重新保存,但不会调用实际的函数。相反,在周围函数返回之前立即调用延迟函数,以与延迟相反的顺序调用。
所以这一行:
defer fmt.Println("our i is", i)
总是意味着fmt.Println()
用i = 0
参数调用:
fmt.Println("our i is", 0)
因为当这条线运行时,i
它的值为0
。
因此,在您的第二个示例中fmt.Println()
prints 0
,然后运行另一个设置i
为的延迟函数,1
这就是返回的内容。
您的第一个示例只是打印一些内容 ( i = 0
),但第一个示例中的延迟函数不会修改的值,i
因此45
将返回(并由 中的fmt.Println()
函数打印main()
)。
- 1 回答
- 0 关注
- 122 浏览
添加回答
举报
0/150
提交
取消