小伙伴写for循环, 提出了一个问题: 为啥下面的不可以这么写 (虽然是新手问题, 但是还是得从源代码解释):

arr := []int32{1, 2, 3, 4, 5}
for _, a := range arr {
   go func(){
      fmt.Println("a: %v", a)
   }()
}

我们编译查看下

go build -gcflags '-l' -o main main.go
go tool objdump -s "main\.test0"  main

我们可以看到

TEXT main.test0(SB) /Users/snow_young/go/src/code.byted.org/im_cloud/teq_stack/main.go
  main.go:14                0x1091cf0                65488b0c2530000000        MOVQ GS:0x30, CX
  main.go:14                0x1091cf9                483b6110                CMPQ 0x10(CX), SP
  main.go:14                0x1091cfd                0f868a000000                JBE 0x1091d8d
  main.go:14                0x1091d03                4883ec48                SUBQ $0x48, SP
  main.go:14                0x1091d07                48896c2440                MOVQ BP, 0x40(SP)
  main.go:14                0x1091d0c                488d6c2440                LEAQ 0x40(SP), BP
  main.go:15                0x1091d11                488b05785e0400                MOVQ main.statictmp_1(SB), AX
  main.go:15                0x1091d18                4889442424                MOVQ AX, 0x24(SP)
  main.go:15                0x1091d1d                0f1005705e0400                MOVUPS main.statictmp_1+4(SB), X0
  main.go:15                0x1091d24                0f11442428                MOVUPS X0, 0x28(SP)
  main.go:16                0x1091d29                488d0550fc0000                LEAQ type.*+63872(SB), AX
  main.go:16                0x1091d30                48890424                MOVQ AX, 0(SP)
  main.go:16                0x1091d34                e8978ff7ff                CALL runtime.newobject(SB)
  main.go:16                0x1091d39                488b442408                MOVQ 0x8(SP), AX
  main.go:16                0x1091d3e                4889442438                MOVQ AX, 0x38(SP)
  main.go:16                0x1091d43                31c9                        XORL CX, CX
  main.go:16                0x1091d45                eb36                        JMP 0x1091d7d
  main.go:16                0x1091d47                48894c2418                MOVQ CX, 0x18(SP)
  main.go:16                0x1091d4c                8b548c24                MOVL 0x24(SP)(CX*4), DX
  main.go:16                0x1091d50                8910                        MOVL DX, 0(AX)
  main.go:19                0x1091d52                4889442410                MOVQ AX, 0x10(SP)
  main.go:17                0x1091d57                c7042408000000                MOVL $0x8, 0(SP)
  main.go:17                0x1091d5e                488d159b7e0300                LEAQ go.func.*+120(SB), DX
  main.go:17                0x1091d65                4889542408                MOVQ DX, 0x8(SP)
  main.go:17                0x1091d6a                e8b1e4f9ff                CALL runtime.newproc(SB)
  main.go:16                0x1091d6f                488b442418                MOVQ 0x18(SP), AX
  main.go:16                0x1091d74                488d4801                LEAQ 0x1(AX), CX
  main.go:16                0x1091d78                488b442438                MOVQ 0x38(SP), AX
  main.go:16                0x1091d7d                4883f905                CMPQ $0x5, CX
  main.go:16                0x1091d81                7cc4                        JL 0x1091d47
  main.go:16                0x1091d83                488b6c2440                MOVQ 0x40(SP), BP
  main.go:16                0x1091d88                4883c448                ADDQ $0x48, SP
  main.go:16                0x1091d8c                c3                        RET
  main.go:14                0x1091d8d                e87ed7fbff                CALL runtime.morestack_noctxt(SB)
  main.go:14                0x1091d92                e959ffffff                JMP main.test0(SB)

可以发下,只实例化了一个对象

main.go:16                0x1091d34                e8978ff7ff                CALL runtime.newobject(SB)

并且执行的时候, 也没有复制对象, 直接就把当前地址传递了过去

  main.go:17                0x1091d6a                e8b1e4f9ff                CALL runtime.newproc(SB)