golang闭包中变量获取

news/2024/9/17 7:19:13/ 标签: golang, 开发语言, 后端

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

案例1:

package main// 探究go语言中闭包如何捕获变量
func main() {i := 10closureByValue := 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-00x0000 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, $-20x0004 00004 (E:/Go/src/tool/closure/closure1/main.go:4)        JLS     550x0006 00006 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-10x0006 00006 (E:/Go/src/tool/closure/closure1/main.go:4)        PUSHQ   BP0x0007 00007 (E:/Go/src/tool/closure/closure1/main.go:4)        MOVQ    SP, BP0x000a 00010 (E:/Go/src/tool/closure/closure1/main.go:4)        SUBQ    $16, SP0x000e 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), AX0x001a 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), AX0x002b 00043 (E:/Go/src/tool/closure/closure1/main.go:9)        LEAQ    main..autotmp_3(SP), DX0x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        PCDATA  $1, $00x002f 00047 (E:/Go/src/tool/closure/closure1/main.go:9)        CALL    AX0x0031 00049 (E:/Go/src/tool/closure/closure1/main.go:10)       ADDQ    $16, SP0x0035 00053 (E:/Go/src/tool/closure/closure1/main.go:10)       POPQ    BP0x0036 00054 (E:/Go/src/tool/closure/closure1/main.go:10)       RET0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:10)       NOP0x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $1, $-10x0037 00055 (E:/Go/src/tool/closure/closure1/main.go:4)        PCDATA  $0, $-20x0037 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, $-10x003c 00060 (E:/Go/src/tool/closure/closure1/main.go:4)        JMP     00x0000 00000 (E:/Go/src/tool/closure/closure1/main.go:6)        TEXT    main.main.func1(SB), NOSPLIT|NEEDCTXT|NOFRAME|ABIInternal, $0-00x0000 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), AX0x0004 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 mainimport ("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 mainimport ("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 mainimport ("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-80x0000 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, $10x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:10)       RET0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       TEXT    main.main(SB), ABIInternal, $32-00x0000 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, $-20x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       JLS     1170x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-10x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PUSHQ   BP0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:17)       MOVQ    SP, BP0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:17)       SUBQ    $24, SP0x000e 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), AX0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:21)       PCDATA  $1, $00x0015 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)       NOP0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:21)       JMP     510x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-20x0022 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, $-10x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $1, $10x0026 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), AX0x0030 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), $100x0037 00055 (E:/Go/src/tool/closure/closure3/main.go:21)       JGE     1110x0039 00057 (E:/Go/src/tool/closure/closure3/main.go:22)       LEAQ    type:noalg.struct { F uintptr; X0 *int }(SB), AX0x0040 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), CX0x004c 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, $-20x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:22)       CMPL    runtime.writeBarrier(SB), $00x0056 00086 (E:/Go/src/tool/closure/closure3/main.go:22)       JNE     960x0058 00088 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    main.&i+16(SP), DX0x005d 00093 (E:/Go/src/tool/closure/closure3/main.go:22)       JMP     340x005f 00095 (E:/Go/src/tool/closure/closure3/main.go:22)       NOP0x0060 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), DX0x006a 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     340x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $0, $-10x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $1, $-10x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       ADDQ    $24, SP0x0073 00115 (E:/Go/src/tool/closure/closure3/main.go:32)       POPQ    BP0x0074 00116 (E:/Go/src/tool/closure/closure3/main.go:32)       RET0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:32)       NOP0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $1, $-10x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-20x0075 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, $-10x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       JMP     00x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:22)       TEXT    main.main.func1(SB), NEEDCTXT|ABIInternal, $16-00x0000 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, $-20x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:22)       JLS     330x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-10x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:22)       PUSHQ   BP0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:22)       MOVQ    SP, BP0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:22)       SUBQ    $8, SP0x000e 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), CX0x0012 00018 (E:/Go/src/tool/closure/closure3/main.go:23)       MOVQ    (CX), AX0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:23)       PCDATA  $1, $00x0015 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, SP0x001e 00030 (E:/Go/src/tool/closure/closure3/main.go:24)       POPQ    BP0x001f 00031 (E:/Go/src/tool/closure/closure3/main.go:24)       NOP0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:24)       RET0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:24)       NOP0x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $1, $-10x0021 00033 (E:/Go/src/tool/closure/closure3/main.go:22)       PCDATA  $0, $-20x0021 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, $-10x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:22)       JMP     0

case5:

package mainimport ("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-80x0000 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, $10x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:14)       MOVQ    (AX), AX0x0003 00003 (E:/Go/src/tool/closure/closure3/main.go:14)       RET0x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:17)       TEXT    main.main(SB), ABIInternal, $32-00x0000 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, $-20x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:17)       JLS     1170x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-10x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:17)       PUSHQ   BP0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:17)       MOVQ    SP, BP0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:17)       SUBQ    $24, SP0x000e 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), AX0x0015 00021 (E:/Go/src/tool/closure/closure3/main.go:26)       PCDATA  $1, $00x0015 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)       NOP0x0020 00032 (E:/Go/src/tool/closure/closure3/main.go:26)       JMP     510x0022 00034 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-20x0022 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, $-10x0026 00038 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $1, $10x0026 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), AX0x0030 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), $100x0037 00055 (E:/Go/src/tool/closure/closure3/main.go:26)       JGE     1110x0039 00057 (E:/Go/src/tool/closure/closure3/main.go:27)       LEAQ    type:noalg.struct { F uintptr; X0 *int }(SB), AX0x0040 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), CX0x004c 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, $-20x004f 00079 (E:/Go/src/tool/closure/closure3/main.go:27)       CMPL    runtime.writeBarrier(SB), $00x0056 00086 (E:/Go/src/tool/closure/closure3/main.go:27)       JNE     960x0058 00088 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    main.&i+16(SP), DX0x005d 00093 (E:/Go/src/tool/closure/closure3/main.go:27)       JMP     340x005f 00095 (E:/Go/src/tool/closure/closure3/main.go:27)       NOP0x0060 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), DX0x006a 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     340x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $0, $-10x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       PCDATA  $1, $-10x006f 00111 (E:/Go/src/tool/closure/closure3/main.go:32)       ADDQ    $24, SP0x0073 00115 (E:/Go/src/tool/closure/closure3/main.go:32)       POPQ    BP0x0074 00116 (E:/Go/src/tool/closure/closure3/main.go:32)       RET0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:32)       NOP0x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $1, $-10x0075 00117 (E:/Go/src/tool/closure/closure3/main.go:17)       PCDATA  $0, $-20x0075 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, $-10x007a 00122 (E:/Go/src/tool/closure/closure3/main.go:17)       JMP     00x0000 00000 (E:/Go/src/tool/closure/closure3/main.go:27)       TEXT    main.main.func1(SB), NEEDCTXT|ABIInternal, $16-00x0000 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, $-20x0004 00004 (E:/Go/src/tool/closure/closure3/main.go:27)       JLS     290x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-10x0006 00006 (E:/Go/src/tool/closure/closure3/main.go:27)       PUSHQ   BP0x0007 00007 (E:/Go/src/tool/closure/closure3/main.go:27)       MOVQ    SP, BP0x000a 00010 (E:/Go/src/tool/closure/closure3/main.go:27)       SUBQ    $8, SP0x000e 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), AX0x0012 00018 (E:/Go/src/tool/closure/closure3/main.go:28)       PCDATA  $1, $00x0012 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, SP0x001b 00027 (E:/Go/src/tool/closure/closure3/main.go:29)       POPQ    BP0x001c 00028 (E:/Go/src/tool/closure/closure3/main.go:29)       RET0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:29)       NOP0x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $1, $-10x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       PCDATA  $0, $-20x001d 00029 (E:/Go/src/tool/closure/closure3/main.go:27)       NOP0x0020 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, $-10x0025 00037 (E:/Go/src/tool/closure/closure3/main.go:27)       JMP     0

 


http://www.ppmy.cn/news/1522114.html

相关文章

ARM SIMD instruction -- fcmpe

FCMPE Floating-point signaling Compare (scalar). This instruction compares the two SIMD&FP source register values, or the first SIMD&FP source register value and zero. It writes the result to the PSTATE.{N, Z, C, V} flags. 浮点数比较&#xff08;标量…

【重学 MySQL】五、MySQL 的卸载

【重学 MySQL】五、MySQL 的卸载 停止MySQL服务卸载MySQL程序删除残余文件清理注册表删除环境变量配置重启电脑 MySQL的卸载过程需要仔细操作&#xff0c;以确保彻底卸载并清理所有相关文件和配置。 停止MySQL服务 打开任务管理器&#xff1a;右键点击任务栏空白处&#xff0…

挂轨巡检机器人在发电厂与煤矿皮带机场景的应用

一、引言 在发电厂和煤矿等重工业领域&#xff0c;皮带机作为关键设备&#xff0c;其运行状态直接关系到生产效率和安全。然而&#xff0c;传统的人工巡检方式不仅效率低下&#xff0c;还存在安全隐患。随着智能巡检技术的不断发展&#xff0c;杭州旗晟智能科技有限公司推出的…

汽车智能驾驶算法汇总

汽车智能驾驶算法是自动驾驶技术的核心&#xff0c;它们集成了多个学科的知识&#xff0c;包括计算机视觉、机器学习、控制理论、路径规划等。以下是对汽车智能驾驶算法的一个详细汇总&#xff0c;内容分为几个关键部分进行阐述。 一、计算机视觉算法 计算机视觉是智能驾驶算…

Gemini AI 与 ChatGPT:哪个更适合为我策划婚礼?

我在六月订婚后&#xff0c;一心想着婚礼钟声&#xff0c;但在看到这些婚礼场地报价后&#xff0c;更像是警铃声响起。 “叮咚”已经被重新混音成“哗啦啦”——我需要帮助。 我甚至不知道如何 开始 计划婚礼。第一步是什么&#xff1f;我需要优先考虑什么&#xff1f;哪些任…

坐牢第三十四天(c++)

一.作业 1.栈的手写 #include <iostream> using namespace std; // 封装一个栈 class stcak { private:int *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参构造函数stcak(int size);// 拷贝构造函数stcak(const s…

深度学习从入门到精通——感知损失介绍及基本实现

Perceptual Losses 感知损失&#xff08;Perceptual Loss&#xff09;感知损失的定义 图像转换问题&#xff08;Image Transformation Tasks&#xff09;现有方法代码解释感知损失&#xff08;Perceptual Loss&#xff09;1. 感知损失的背景2. 感知损失的定义3. 感知损失的优点…

[数据集][目标检测]抽烟检测数据集VOC+YOLO格式22559张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;22559 标注数量(xml文件个数)&#xff1a;22559 标注数量(txt文件个数)&#xff1a;22559 标…

MATLAB中的线性规划与非线性规划

目录 1. 引言 2. 线性规划&#xff08;LP&#xff09; 2.1 线性规划的基本概念 2.2 MATLAB中的线性规划求解 2.3 线性规划的应用 3. 非线性规划&#xff08;NLP&#xff09; 3.1 非线性规划的基本概念 3.2 MATLAB中的非线性规划求解 3.3 非线性规划的应用 4. 线性规划…

Opencv中的直方图(2)计算图像的直方图函数calcHist()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算一组数组的直方图。 函数 cv::calcHist 计算一个或多个数组的直方图。用于递增直方图bin的元组的元素是从相同位置的相应输入数组中获取的。…

【kubernetes】配置管理中心Configmap运用

一&#xff0c;介绍 Configmap&#xff08;简写 cm&#xff09;是k8s中的资源对象&#xff0c;用于保存非机密性的配置的&#xff0c;数据可以用key/value键值对的形式保存&#xff0c;也可通过文件的形式保存。 【局限性】&#xff1a;在ConfigMap不是用来保存大量数据的&am…

什么是银行挤兑

银行挤兑是指大量银行客户因为对银行失去信心&#xff0c;担心银行可能无法满足其提款需求&#xff0c;而纷纷在短时间内集中到银行提取现金或转账的行为。这种情况可能会导致银行现金储备迅速减少&#xff0c;进而影响银行的正常运营和金融市场的稳定。 银行挤兑通常发生在以下…

中秋将至,邮寄中秋礼品怎么才安心?

中秋节&#xff0c;是中华民族的传统佳节&#xff0c;承载着人们对团圆的期盼和对亲人的思念。在这个温馨的节日里&#xff0c;中秋礼品成为了许多人传递情感的方式。 在这个数字化的时代&#xff0c;虽然一通电话、一个视频就能拉近人与人之间的距离&#xff0c;但一份实实在在…

Oracle中关于not in的替代方案

Oracle优化连接查询速度 样例exists模式Left join模式 今天在使用dblink的时候&#xff0c;多表关联时发现条件中使用 not in 作为条件&#xff0c;会极大的影响查询速度&#xff0c;尤其是not in中的表数据量很大时&#xff0c;简直是一种灾难&#xff1b;经过翻阅资料&#…

opencv学习:形态学操作和边缘检测算子

cv2.morphologyEx() 是 OpenCV 库中的一个函数&#xff0c;用于执行更复杂的形态学操作。这个函数可以执行开运算、闭运算、梯度运算、膨胀、腐蚀以及顶帽和黑帽转换等。这些操作通常用于图像预处理&#xff0c;如去除噪声、平滑边界、突出特征等。 dst cv2.morphologyEx(src…

构建现代前端应用的利器:深入解析Webpack与Vite的差异与优势

Webpack与Vite概述 在现代前端开发中&#xff0c;构建工具是不可或缺的&#xff0c;它们帮助我们打包、优化和管理项目中的资源。Webpack和Vite是当前流行的两个构建工具&#xff0c;它们各自有着独特的优势和工作机制。 Webpack详解 1. Webpack是什么&#xff1f; Webpack…

数据结构基本知识

一、什么是数据结构 1.1、组织存储数据 ---------》内存&#xff08;存储&#xff09; 1.2、研究目的 如何存储数据&#xff08;变量&#xff0c;数组....)程序数据结构算法 1.3、常见保存数据的方法 数组&#xff1a;保存自己的数据指针&#xff1a;是间接访问已经存在的…

2.2ceph集群部署准备-软件准备上

系统的选择 操作系统的选取&#xff0c;除了要考虑ceph本身的运行&#xff0c;一般情况下还需要考虑的因素有如下几点 系统本身的稳定性 目前稳定可靠的系统主要是基于x86和arm的linux系统&#xff0c;ceph并不能安装到windows上&#xff0c;分支上&#xff0c;debian和redhat…

Java后端分布式系统的服务降级:优雅降级与服务熔断

Java后端分布式系统的服务降级&#xff1a;优雅降级与服务熔断 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在分布式系统中&#xff0c;服务降级是一种应对高负载或服务不稳定情况的策略&am…

第十章 【后端】环境准备(10.4)——Vagrant

10.4 Vagrant Vagrant 官网 Vagrant 镜像仓库 下载 安装 直接 install。 设置环境变量 Vagrant 默认将镜像保存在用户文件夹的 .vagrant.d 目录下,若用户文件夹在C盘,下载的镜像文件会大量占用C盘空间。设置环境变量 VAGRANT_HOME 后,Vagrant 会将镜像保存到环境变量指定…