Golang defer中修改返回值

栏目: Go · 发布时间: 5年前

内容简介:我们来看demo:可以看一下汇编码,参考:

我们来看demo:

package main

func foo() (i int) {
    defer func() { i++ }()
    return
}

func bar() (i int) {
    i++
    return
}

func baz() int {
    i := 0
    i++
    return i
}

func main() {
    foo()
    bar()
    baz()
}

可以看一下汇编码, -N 是指禁止编译器优化, -S 是指打印出汇编码。

$ go tool compile -N -S main.go
"".foo STEXT size=117 args=0x8 locals=0x20
    0x0000 00000 (main.go:3)    TEXT    "".foo(SB), $32-8
    0x0000 00000 (main.go:3)    MOVQ    (TLS), CX
    0x0009 00009 (main.go:3)    CMPQ    SP, 16(CX)
    0x000d 00013 (main.go:3)    JLS 110
    0x000f 00015 (main.go:3)    SUBQ    $32, SP
    0x0013 00019 (main.go:3)    MOVQ    BP, 24(SP)
    0x0018 00024 (main.go:3)    LEAQ    24(SP), BP
    0x001d 00029 (main.go:3)    FUNCDATA    $0, gclocals·2a5305abe05176240e61b8620e19a815(SB)
    0x001d 00029 (main.go:3)    FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x001d 00029 (main.go:3)    MOVQ    $0, "".i+40(SP)
    0x0026 00038 (main.go:4)    LEAQ    "".i+40(SP), AX
    0x002b 00043 (main.go:4)    MOVQ    AX, 16(SP)
    0x0030 00048 (main.go:4)    MOVL    $8, (SP)
    0x0037 00055 (main.go:4)    LEAQ    "".foo.func1·f(SB), AX
    0x003e 00062 (main.go:4)    MOVQ    AX, 8(SP)
    0x0043 00067 (main.go:4)    PCDATA  $0, $0
    0x0043 00067 (main.go:4)    CALL    runtime.deferproc(SB)
    0x0048 00072 (main.go:4)    TESTL   AX, AX
    0x004a 00074 (main.go:4)    JNE 94
    0x004c 00076 (main.go:4)    JMP 78
    0x004e 00078 (main.go:5)    PCDATA  $0, $0
    0x004e 00078 (main.go:5)    XCHGL   AX, AX
    0x004f 00079 (main.go:5)    CALL    runtime.deferreturn(SB)
    0x0054 00084 (main.go:5)    MOVQ    24(SP), BP
    0x0059 00089 (main.go:5)    ADDQ    $32, SP
    0x005d 00093 (main.go:5)    RET
    0x005e 00094 (main.go:4)    PCDATA  $0, $0
    0x005e 00094 (main.go:4)    XCHGL   AX, AX
    0x005f 00095 (main.go:4)    CALL    runtime.deferreturn(SB)
    0x0064 00100 (main.go:4)    MOVQ    24(SP), BP
    0x0069 00105 (main.go:4)    ADDQ    $32, SP
    0x006d 00109 (main.go:4)    RET
    0x006e 00110 (main.go:4)    NOP
    0x006e 00110 (main.go:3)    PCDATA  $0, $-1
    0x006e 00110 (main.go:3)    CALL    runtime.morestack_noctxt(SB)
    0x0073 00115 (main.go:3)    JMP 0
    0x0000 65 48 8b 0c 25 00 00 00 00 48 3b 61 10 76 5f 48  eH..%....H;a.v_H
    0x0010 83 ec 20 48 89 6c 24 18 48 8d 6c 24 18 48 c7 44  .. H.l$.H.l$.H.D
    0x0020 24 28 00 00 00 00 48 8d 44 24 28 48 89 44 24 10  $(....H.D$(H.D$.
    0x0030 c7 04 24 08 00 00 00 48 8d 05 00 00 00 00 48 89  ..$....H......H.
    0x0040 44 24 08 e8 00 00 00 00 85 c0 75 12 eb 00 90 e8  D$........u.....
    0x0050 00 00 00 00 48 8b 6c 24 18 48 83 c4 20 c3 90 e8  ....H.l$.H.. ...
    0x0060 00 00 00 00 48 8b 6c 24 18 48 83 c4 20 c3 e8 00  ....H.l$.H.. ...
    0x0070 00 00 00 eb 8b                                   .....
    rel 5+4 t=16 TLS+0
    rel 58+4 t=15 "".foo.func1·f+0
    rel 68+4 t=8 runtime.deferproc+0
    rel 80+4 t=8 runtime.deferreturn+0
    rel 96+4 t=8 runtime.deferreturn+0
    rel 111+4 t=8 runtime.morestack_noctxt+0
"".bar STEXT nosplit size=50 args=0x8 locals=0x10
    0x0000 00000 (main.go:8)    TEXT    "".bar(SB), NOSPLIT, $16-8
    0x0000 00000 (main.go:8)    SUBQ    $16, SP
    0x0004 00004 (main.go:8)    MOVQ    BP, 8(SP)
    0x0009 00009 (main.go:8)    LEAQ    8(SP), BP
    0x000e 00014 (main.go:8)    FUNCDATA    $0, gclocals·2a5305abe05176240e61b8620e19a815(SB)
    0x000e 00014 (main.go:8)    FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x000e 00014 (main.go:8)    MOVQ    $0, "".i+24(SP)
    0x0017 00023 (main.go:9)    MOVQ    $0, ""..autotmp_1(SP)
    0x001f 00031 (main.go:9)    MOVQ    $1, "".i+24(SP)
    0x0028 00040 (main.go:10)   MOVQ    8(SP), BP
    0x002d 00045 (main.go:10)   ADDQ    $16, SP
    0x0031 00049 (main.go:10)   RET
    0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 c7  H...H.l$.H.l$.H.
    0x0010 44 24 18 00 00 00 00 48 c7 04 24 00 00 00 00 48  D$.....H..$....H
    0x0020 c7 44 24 18 01 00 00 00 48 8b 6c 24 08 48 83 c4  .D$.....H.l$.H..
    0x0030 10 c3                                            ..
"".baz STEXT nosplit size=67 args=0x8 locals=0x18
    0x0000 00000 (main.go:13)   TEXT    "".baz(SB), NOSPLIT, $24-8
    0x0000 00000 (main.go:13)   SUBQ    $24, SP
    0x0004 00004 (main.go:13)   MOVQ    BP, 16(SP)
    0x0009 00009 (main.go:13)   LEAQ    16(SP), BP
    0x000e 00014 (main.go:13)   FUNCDATA    $0, gclocals·2a5305abe05176240e61b8620e19a815(SB)
    0x000e 00014 (main.go:13)   FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x000e 00014 (main.go:13)   MOVQ    $0, "".~r0+32(SP)
    0x0017 00023 (main.go:14)   MOVQ    $0, "".i(SP)
    0x001f 00031 (main.go:15)   MOVQ    $0, ""..autotmp_2+8(SP)
    0x0028 00040 (main.go:15)   MOVQ    $1, "".i(SP)
    0x0030 00048 (main.go:16)   MOVQ    "".i(SP), AX
    0x0034 00052 (main.go:16)   MOVQ    AX, "".~r0+32(SP)
    0x0039 00057 (main.go:16)   MOVQ    16(SP), BP
    0x003e 00062 (main.go:16)   ADDQ    $24, SP
    0x0042 00066 (main.go:16)   RET
    0x0000 48 83 ec 18 48 89 6c 24 10 48 8d 6c 24 10 48 c7  H...H.l$.H.l$.H.
    0x0010 44 24 20 00 00 00 00 48 c7 04 24 00 00 00 00 48  D$ ....H..$....H
    0x0020 c7 44 24 08 00 00 00 00 48 c7 04 24 01 00 00 00  .D$.....H..$....
    0x0030 48 8b 04 24 48 89 44 24 20 48 8b 6c 24 10 48 83  H..$H.D$ H.l$.H.
    0x0040 c4 18 c3                                         ...

参考:

问我为什么不讲解一下上面的汇编代码?因为我也看不懂汇编-。-。不过可以连蒙带猜。

结合文档,named return values会在函数开始时自动声明。而匿名返回值则是相当于自动生成了一个变量 存储返回值。defer会在函数真正返回之前执行。所以defer可以修改named return values,但是匿名返回值 不能修改。


以上所述就是小编给大家介绍的《Golang defer中修改返回值》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Release It!

Release It!

Michael T. Nygard / Pragmatic Bookshelf / 2007-03-30 / USD 34.95

“Feature complete” is not the same as “production ready.” Whether it’s in Java, .NET, or Ruby on Rails, getting your application ready to ship is only half the battle. Did you design your system to......一起来看看 《Release It!》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具