为了账号安全,请及时绑定邮箱和手机立即绑定

函数返回的常量是否自动成为命名返回变量的值

函数返回的常量是否自动成为命名返回变量的值

Go
繁星点点滴滴 2021-11-15 17:17:12
这是 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())。


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信