golang闭包中变量获取

闭包的本质是一个语法糖,其本质是获取外部变量在其内部使用。文中case2和case3并未涉及闭包,只是作为对比案例。case4这个案例有点不能理解,汇编看着太吃力了。case4和case5留待后续再研究。

案例1:

package main

// 探究go语言中闭包如何捕获变量
func main() {
	i := 10
	closureByValue := func() int {
		return i
	}
	closureByValue()
}

我们直接利用go的compile工具看一下汇编的情况。我用的是windows电脑,在命令行终端敲上这个命令:

go tool compile -l -S main.go | findstr "main.go"
 0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:4)        TEXT    main.main(SB), ABIInternal, $24-0
        0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:4)        CMPQ    SP, 16(R14)
        0x0004 00004 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-2
        0x0004 00004 (E:/Go/src/tool/closure/closure1/main.go:4)        JLS     55
        0x0006 00006 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-1
        0x0006 00006 (E:/Go/src/tool/closure/closure1/main.go:4)        PUSHQ   BP
        0x0007 00007 (E:/Go/src/tool/closure/closure1/main.go:4)        MOVQ    SP, BP
        0x000a 00010 (E:/Go/src/tool/closure/closure1/main.go:4)        SUBQ    $16, SP
        0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:4)        FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:4)        FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVUPS  X15, main..autotmp_3(SP)
        0x0013 00019 (E:/Go/src/tool/closure/closure1/main.go:6)        LEAQ    main.main.func1(SB), AX
        0x001a 00026 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVQ    AX, main..autotmp_3(SP)
        0x001e 00030 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVQ    $10, main..autotmp_3+8(SP)
        0x0027 00039 (E:/Go/src/tool/closure/closure1/main.go:9)        MOVQ    main..autotmp_3(SP), AX
        0x002b 00043 (E:/Go/src/tool/closure/closure1/main.go:9)        LEAQ    main..autotmp_3(SP), DX
        0x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        PCDATA  $1, $0
        0x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        CALL    AX
        0x0031 00049 (E:/Go/src/tool/closure/closure1/main.go:10)       ADDQ    $16, SP
        0x0035 00053 (E:/Go/src/tool/closure/closure1/main.go:10)       POPQ    BP
        0x0036 00054 (E:/Go/src/tool/closure/closure1/main.go:10)       RET
        0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:10)       NOP
        0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $1, $-1
        0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-2
        0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:4)        CALL    runtime.morestack_noctxt(SB)
        0x003c 00060 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-1
        0x003c 00060 (E:/Go/src/tool/closure/closure1/main.go:4)        JMP     0
        0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:6)        TEXT    main.main.func1(SB), NOSPLIT|NEEDCTXT|NOFRAME|ABIInternal, $0-0
        0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:6)        FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:6)        FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVQ    8(DX), AX
        0x0004 00004 (E:/Go/src/tool/closure/closure1/main.go:7)        RET

我们重点关注闭包函数及变量。

函数数据与局部变量的初始化

0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:4)        FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)  
0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:4)        FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)  
0x000e 00014 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVUPS  X15, main..autotmp_3(SP)  
0x0013 00019 (E:/Go/src/tool/closure/closure1/main.go:6)        LEAQ    main.main.func1(SB), AX  
0x001a 00026 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVQ    AX, main..autotmp_3(SP)  
0x001e 00030 (E:/Go/src/tool/closure/closure1/main.go:6)        MOVQ    $10, main..autotmp_3+8(SP)
  • FUNCDATA 包含一些垃圾收集器使用的元数据。
  • MOVUPS 将X15寄存器的内容复制到栈上的局部变量main..autotmp_3
  • LEAQ 加载main.main.func1的地址到AX寄存器。
  • MOVQ AX, main..autotmp_3(SP) 将AX的值(即main.main.func1的地址)存储到栈上。
  • MOVQ $10, main..autotmp_3+8(SP) 将常数10存储到栈上的另一个位置。

调用闭包函数

0x0027 00039 (E:/Go/src/tool/closure/closure1/main.go:9)        MOVQ    main..autotmp_3(SP), AX  
0x002b 00043 (E:/Go/src/tool/closure/closure1/main.go:9)        LEAQ    main..autotmp_3(SP), DX  
0x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        PCDATA  $1, $0  
0x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        CALL    AX
  • MOVQ main..autotmp_3(SP), AX 将闭包函数的地址从栈加载到AX寄存器。
  • LEAQ main..autotmp_3(SP), DX 将闭包数据的地址加载到DX寄存器。
  • CALL AX 调用AX寄存器中地址指向的函数,即main.main.func1

 所以,闭包实际上,是把函数外的变量复制到了函数内,供函数内部使用。

案例2:

package main

import (
	"fmt"
	"time"
)

func passByValue(value int) {
	fmt.Println(value)
}

func main() {
	for i := 0; i < 10; i++ {
		go passByValue(i)
	}
	time.Sleep(time.Second * 100)
}

这种情况下输出的结果是符合我们的预期的。因为,虽然起了协程,在这个循环中,每次迭代,i 的值会被传递到 passByValue 中。

案例3:

package main

import (
	"fmt"
	"time"
)
func passByRef(value *int) int {
    fmt.Println(*value)
	return *value
}

func main() {
	for i := 0; i < 10; i++ {
		go passByRef(&i)
	}
	time.Sleep(time.Second * 100)
}

大家猜一下,这种情况下,这种情况下输出的是什么?

这种情况似乎是可以理解的,所有的 goroutine 都在并发执行,并且它们都共享同一个 i 变量的地址。由于 for 循环在 goroutine 启动后继续执行,并且 i 的值会在每次迭代中增加,最终所有 goroutine 都会打印出 i 的最终值。

因此,输出的结果将是 10,因为当所有 goroutine 开始执行时,i 的值已经增加到 10。具体来说,可能会打印出多次 10,具体数量取决于 goroutine 的调度。我的版本是go1.21.5

这里我的函数名是passByRef,似乎有点让人误解,让人误以为是传引用的传参方式,go里面其实没有这种用法,本质上只是拷贝指针的地址传递到函数内。关于这个问题的探究,我在另一篇文章中《golang函数传参——值传递理解》有写过,有兴趣的可以移步过去看看。

但是在go的在线工具中执行,却是这种结果,有点不能理解啊。 这个是go1.22的版本,执行的结果。难道新版本有什么改动么?这个遗留问题,后续有时间再研究研究。

case4:

package main

import (
	"fmt"
	"time"
)

func passByVal(value int) int {
	fmt.Println(value)
	return value
}

func main() {
	for i := 0; i < 10; i++ {
		go func() {
			passByVal(i)
		}()
	}
	time.Sleep(time.Second * 100)
}

先看起其执行结果。

再来思考一下,为什么会是这样的执行结果。 

首先,看一下汇编的结果。

0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        TEXT    main.passByVal(SB), NOSPLIT|NOFRAME|ABIInternal, $0-8
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        FUNCDATA        $5, main.passByVal.arginfo1(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        FUNCDATA        $6, main.passByVal.argliveinfo(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:8)        PCDATA  $3, $1
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:10)       RET
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       TEXT    main.main(SB), ABIInternal, $32-0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       CMPQ    SP, 16(R14)
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-2
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       JLS     117
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-1
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PUSHQ   BP
        0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:17)       MOVQ    SP, BP
        0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:17)       SUBQ    $24, SP
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:17)       FUNCDATA        $0, gclocals?J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:17)       FUNCDATA        $1, gclocals?CnDyI2HjYXFz19SsOj98tw==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:21)       LEAQ    type:int(SB), AX
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:21)       PCDATA  $1, $0
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:21)       CALL    runtime.newobject(SB)
        0x001a 00026 (E:/Go/src/tool/closure/closure3/main.go:21)       MOVQ    AX, main.&i+16(SP)
        0x001f 00031 (E:/Go/src/tool/closure/closure3/main.go:21)       NOP
        0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:21)       JMP     51
        0x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-2
        0x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    DX, 8(AX)
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-1
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $1, $1
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       CALL    runtime.newproc(SB)
        0x002b 00043 (E:/Go/src/tool/closure/closure3/main.go:21)       MOVQ    main.&i+16(SP), AX
        0x0030 00048 (E:/Go/src/tool/closure/closure3/main.go:21)       INCQ    (AX)
        0x0033 00051 (E:/Go/src/tool/closure/closure3/main.go:21)       CMPQ    (AX), $10
        0x0037 00055 (E:/Go/src/tool/closure/closure3/main.go:21)       JGE     111
        0x0039 00057 (E:/Go/src/tool/closure/closure3/main.go:22)       LEAQ    type:noalg.struct { F uintptr; X0 *int }(SB), AX
        0x0040 00064 (E:/Go/src/tool/closure/closure3/main.go:22)       CALL    runtime.newobject(SB)
        0x0045 00069 (E:/Go/src/tool/closure/closure3/main.go:22)       LEAQ    main.main.func1(SB), CX
        0x004c 00076 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    CX, (AX)
        0x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-2
        0x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:22)       CMPL    runtime.writeBarrier(SB), $0
        0x0056 00086 (E:/Go/src/tool/closure/closure3/main.go:22)       JNE     96
        0x0058 00088 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    main.&i+16(SP), DX
        0x005d 00093 (E:/Go/src/tool/closure/closure3/main.go:22)       JMP     34
        0x005f 00095 (E:/Go/src/tool/closure/closure3/main.go:22)       NOP
        0x0060 00096 (E:/Go/src/tool/closure/closure3/main.go:22)       CALL    runtime.gcWriteBarrier1(SB)
        0x0065 00101 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    main.&i+16(SP), DX
        0x006a 00106 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    DX, (R11)
        0x006d 00109 (E:/Go/src/tool/closure/closure3/main.go:22)       JMP     34
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $0, $-1
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $1, $-1
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       ADDQ    $24, SP
        0x0073 00115 (E:/Go/src/tool/closure/closure3/main.go:32)       POPQ    BP
        0x0074 00116 (E:/Go/src/tool/closure/closure3/main.go:32)       RET
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:32)       NOP
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $1, $-1
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-2
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       CALL    runtime.morestack_noctxt(SB)
        0x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-1
        0x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       JMP     0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:22)       TEXT    main.main.func1(SB), NEEDCTXT|ABIInternal, $16-0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:22)       CMPQ    SP, 16(R14)
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-2
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:22)       JLS     33
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-1
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:22)       PUSHQ   BP
        0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    SP, BP
        0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:22)       SUBQ    $8, SP
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:22)       FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:22)       FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    8(DX), CX
        0x0012 00018 (E:/Go/src/tool/closure/closure3/main.go:23)       MOVQ    (CX), AX
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:23)       PCDATA  $1, $0
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:23)       CALL    main.passByVal(SB)
        0x001a 00026 (E:/Go/src/tool/closure/closure3/main.go:24)       ADDQ    $8, SP
        0x001e 00030 (E:/Go/src/tool/closure/closure3/main.go:24)       POPQ    BP
        0x001f 00031 (E:/Go/src/tool/closure/closure3/main.go:24)       NOP
        0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:24)       RET
        0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:24)       NOP
        0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $1, $-1
        0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-2
        0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:22)       CALL    runtime.morestack(SB)
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-1
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       JMP     0

case5:

package main

import (
	"fmt"
	"time"
)

func passByRef(value *int) int {
	fmt.Println(*value)
	return *value
}

func main() {
	for i := 0; i < 10; i++ {
		go func() {
			passByRef(&i)
		}()
	}
	time.Sleep(time.Second * 100)
}

同样的先看一下其执行结果:

再结合其汇编代码看一下为什么会是这样的结果。

 0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       TEXT    main.passByRef(SB), NOSPLIT|NOFRAME|ABIInternal, $0-8
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       FUNCDATA        $0, gclocals?wgcWObbY2HYnK2SU/U22lA==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       FUNCDATA        $1, gclocals?J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       FUNCDATA        $5, main.passByRef.arginfo1(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       FUNCDATA        $6, main.passByRef.argliveinfo(SB)
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:12)       PCDATA  $3, $1
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:14)       MOVQ    (AX), AX
        0x0003 00003 (E:/Go/src/tool/closure/closure3/main.go:14)       RET
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       TEXT    main.main(SB), ABIInternal, $32-0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       CMPQ    SP, 16(R14)
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-2
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       JLS     117
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-1
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PUSHQ   BP
        0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:17)       MOVQ    SP, BP
        0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:17)       SUBQ    $24, SP
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:17)       FUNCDATA        $0, gclocals?J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:17)       FUNCDATA        $1, gclocals?CnDyI2HjYXFz19SsOj98tw==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:26)       LEAQ    type:int(SB), AX
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:26)       PCDATA  $1, $0
        0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:26)       CALL    runtime.newobject(SB)
        0x001a 00026 (E:/Go/src/tool/closure/closure3/main.go:26)       MOVQ    AX, main.&i+16(SP)
        0x001f 00031 (E:/Go/src/tool/closure/closure3/main.go:26)       NOP
        0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:26)       JMP     51
        0x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-2
        0x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    DX, 8(AX)
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-1
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $1, $1
        0x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:27)       CALL    runtime.newproc(SB)
        0x002b 00043 (E:/Go/src/tool/closure/closure3/main.go:26)       MOVQ    main.&i+16(SP), AX
        0x0030 00048 (E:/Go/src/tool/closure/closure3/main.go:26)       INCQ    (AX)
        0x0033 00051 (E:/Go/src/tool/closure/closure3/main.go:26)       CMPQ    (AX), $10
        0x0037 00055 (E:/Go/src/tool/closure/closure3/main.go:26)       JGE     111
        0x0039 00057 (E:/Go/src/tool/closure/closure3/main.go:27)       LEAQ    type:noalg.struct { F uintptr; X0 *int }(SB), AX
        0x0040 00064 (E:/Go/src/tool/closure/closure3/main.go:27)       CALL    runtime.newobject(SB)
        0x0045 00069 (E:/Go/src/tool/closure/closure3/main.go:27)       LEAQ    main.main.func1(SB), CX
        0x004c 00076 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    CX, (AX)
        0x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-2
        0x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:27)       CMPL    runtime.writeBarrier(SB), $0
        0x0056 00086 (E:/Go/src/tool/closure/closure3/main.go:27)       JNE     96
        0x0058 00088 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    main.&i+16(SP), DX
        0x005d 00093 (E:/Go/src/tool/closure/closure3/main.go:27)       JMP     34
        0x005f 00095 (E:/Go/src/tool/closure/closure3/main.go:27)       NOP
        0x0060 00096 (E:/Go/src/tool/closure/closure3/main.go:27)       CALL    runtime.gcWriteBarrier1(SB)
        0x0065 00101 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    main.&i+16(SP), DX
        0x006a 00106 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    DX, (R11)
        0x006d 00109 (E:/Go/src/tool/closure/closure3/main.go:27)       JMP     34
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $0, $-1
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $1, $-1
        0x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       ADDQ    $24, SP
        0x0073 00115 (E:/Go/src/tool/closure/closure3/main.go:32)       POPQ    BP
        0x0074 00116 (E:/Go/src/tool/closure/closure3/main.go:32)       RET
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:32)       NOP
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $1, $-1
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-2
        0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       CALL    runtime.morestack_noctxt(SB)
        0x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-1
        0x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       JMP     0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:27)       TEXT    main.main.func1(SB), NEEDCTXT|ABIInternal, $16-0
        0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:27)       CMPQ    SP, 16(R14)
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-2
        0x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:27)       JLS     29
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-1
        0x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:27)       PUSHQ   BP
        0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    SP, BP
        0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:27)       SUBQ    $8, SP
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:27)       FUNCDATA        $0, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:27)       FUNCDATA        $1, gclocals?g2BeySu+wFnoycgXfElmcg==(SB)
        0x000e 00014 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    8(DX), AX
        0x0012 00018 (E:/Go/src/tool/closure/closure3/main.go:28)       PCDATA  $1, $0
        0x0012 00018 (E:/Go/src/tool/closure/closure3/main.go:28)       CALL    main.passByRef(SB)
        0x0017 00023 (E:/Go/src/tool/closure/closure3/main.go:29)       ADDQ    $8, SP
        0x001b 00027 (E:/Go/src/tool/closure/closure3/main.go:29)       POPQ    BP
        0x001c 00028 (E:/Go/src/tool/closure/closure3/main.go:29)       RET
        0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:29)       NOP
        0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $1, $-1
        0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-2
        0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       NOP
        0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:27)       CALL    runtime.morestack(SB)
        0x0025 00037 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-1
        0x0025 00037 (E:/Go/src/tool/closure/closure3/main.go:27)       JMP     0

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值