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

关于延迟行为的 Go 语言面试问题

关于延迟行为的 Go 语言面试问题

Go
小怪兽爱吃肉 2022-04-26 19:38:56
我有 2 个代码示例:func test() int {    var x int    defer func() {        x++    }()    x = 1    return x}func main() {    fmt.Println(test())}它返回:1。但是,以下代码示例的行为有所不同:func test() (x int) {    defer func() {        x++    }()    x = 1    return}func main() {    fmt.Println(test())}它返回2。为了了解发生了什么,我反汇编了代码。对于第一个代码片段(其输出为1):  main.go:19            0x48cf40                64488b0c25f8ffffff      MOVQ FS:0xfffffff8, CX  main.go:19            0x48cf49                483b6110                CMPQ 0x10(CX), SP  main.go:19            0x48cf4d                7678                    JBE 0x48cfc7  main.go:19            0x48cf4f                4883ec58                SUBQ $0x58, SP  main.go:19            0x48cf53                48896c2450              MOVQ BP, 0x50(SP)  main.go:19            0x48cf58                488d6c2450              LEAQ 0x50(SP), BP  main.go:20            0x48cf5d                e83effffff              CALL main.test(SB)  main.go:20            0x48cf62                e8c9bff7ff              CALL runtime.convT64(SB)  main.go:20            0x48cf67                488b442408              MOVQ 0x8(SP), AX  main.go:20            0x48cf6c                0f57c0                  XORPS X0, X0  main.go:20            0x48cf6f                0f11442440              MOVUPS X0, 0x40(SP)
查看完整描述

1 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

Golang 规范对 defer 语句这样说:

[...] 如果延迟函数是函数字面量,并且周围的函数具有在字面量范围内的命名结果参数,则延迟函数可以在返回结果参数之前访问和修改结果参数。

(我的重点)

您的第一个片段中,函数test没有命名返回参数;x只是一个局部变量。因此,您的 defer 语句不能修改 function 的结果test

您的第二个片段中,函数test有一个命名的返回参数x,它在您的函数文字范围内。因此, defer 语句可以(并且确实)修改了 function 的结果test


查看完整回答
反对 回复 2022-04-26
  • 1 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

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