三种情况:
package main
import "fmt"
func main() {
a := 0
tp := 0
b := &tp
// condition 3
defer func() {
fmt.Println(a)
fmt.Println(*b)
fmt.Println("condition 3 end============")
}()
// condition 2
defer fmt.Println("condition 2 end============")
defer fmt.Println(*b)
defer fmt.Println(a)
// condition 1
defer func(a int, b *int) {
fmt.Println(a)
fmt.Println(*b)
fmt.Println("condition 1 end============")
}(a, b)
a = 1
*b = 2
}
输出:
0
2
condition 1 end============
0
0
condition 2 end============
1
2
condition 3 end============
具体原因可以参考汇编代码:
"".main STEXT size=646 args=0x0 locals=0x88
0x0000 00000 (boot.go:5) TEXT "".main(SB), ABIInternal, $136-0
0x0000 00000 (boot.go:5) MOVQ TLS, CX
0x0009 00009 (boot.go:5) MOVQ (CX)(TLS*2), CX
0x0010 00016 (boot.go:5) LEAQ -8(SP), AX
0x0015 00021 (boot.go:5) CMPQ AX, 16(CX)
0x0019 00025 (boot.go:5) JLS 636
0x001f 00031 (boot.go:5) SUBQ $136, SP
0x0026 00038 (boot.go:5) MOVQ BP, 128(SP)
0x002e 00046 (boot.go:5) LEAQ 128(SP), BP
0x0036 00054 (boot.go:5) FUNCDATA $0, gclocals·3e27b3aa6b89137cce48b3379a2a6610(SB)
0x0036 00054 (boot.go:5) FUNCDATA $1, gclocals·8d8af7cdb400daeb6b006e733bd0e383(SB)
0x0036 00054 (boot.go:5) FUNCDATA $3, gclocals·e0c93e5d9179a75f8f23b149ced9dbf5(SB)
0x0036 00054 (boot.go:5) FUNCDATA $4, "".main.stkobj(SB)
0x0036 00054 (boot.go:6) PCDATA $2, $0
0x0036 00054 (boot.go:6) PCDATA $0, $0
0x0036 00054 (boot.go:6) MOVQ $0, "".a+64(SP)
0x003f 00063 (boot.go:7) PCDATA $2, $1
0x003f 00063 (boot.go:7) LEAQ type.int(SB), AX
0x0046 00070 (boot.go:7) PCDATA $2, $0
0x0046 00070 (boot.go:7) MOVQ AX, (SP)
0x004a 00074 (boot.go:7) CALL runtime.newobject(SB)
0x004f 00079 (boot.go:7) PCDATA $2, $1
0x004f 00079 (boot.go:7) MOVQ 8(SP), AX
0x0054 00084 (boot.go:7) PCDATA $0, $1
0x0054 00084 (boot.go:7) MOVQ AX, "".b+72(SP)
0x0059 00089 (boot.go:10) MOVL $16, (SP)
0x0060 00096 (boot.go:10) PCDATA $2, $2
0x0060 00096 (boot.go:10) LEAQ "".main.func1·f(SB), CX
0x0067 00103 (boot.go:10) PCDATA $2, $1
0x0067 00103 (boot.go:10) MOVQ CX, 8(SP)
0x006c 00108 (boot.go:10) PCDATA $2, $2
0x006c 00108 (boot.go:10) LEAQ "".a+64(SP), CX
0x0071 00113 (boot.go:10) PCDATA $2, $1
0x0071 00113 (boot.go:10) MOVQ CX, 16(SP)
0x0076 00118 (boot.go:10) PCDATA $2, $0
0x0076 00118 (boot.go:10) MOVQ AX, 24(SP)
0x007b 00123 (boot.go:10) CALL runtime.deferproc(SB)
0x0080 00128 (boot.go:10) TESTL AX, AX
0x0082 00130 (boot.go:10) JNE 614
0x0088 00136 (boot.go:16) PCDATA $0, $2
0x0088 00136 (boot.go:16) XORPS X0, X0
0x008b 00139 (boot.go:16) MOVUPS X0, ""..autotmp_9+80(SP)
0x0090 00144 (boot.go:16) PCDATA $2, $1
0x0090 00144 (boot.go:16) LEAQ type.string(SB), AX
0x0097 00151 (boot.go:16) PCDATA $2, $0
0x0097 00151 (boot.go:16) MOVQ AX, ""..autotmp_9+80(SP)
0x009c 00156 (boot.go:16) PCDATA $2, $1
0x009c 00156 (boot.go:16) LEAQ "".statictmp_0(SB), AX
0x00a3 00163 (boot.go:16) PCDATA $2, $0
0x00a3 00163 (boot.go:16) MOVQ AX, ""..autotmp_9+88(SP)
0x00a8 00168 (boot.go:16) MOVL $48, (SP)
0x00af 00175 (boot.go:16) PCDATA $2, $1
0x00af 00175 (boot.go:16) LEAQ fmt.Println·f(SB), AX
0x00b6 00182 (boot.go:16) PCDATA $2, $0
0x00b6 00182 (boot.go:16) MOVQ AX, 8(SP)
0x00bb 00187 (boot.go:16) PCDATA $2, $3
0x00bb 00187 (boot.go:16) PCDATA $0, $1
0x00bb 00187 (boot.go:16) LEAQ ""..autotmp_9+80(SP), CX
0x00c0 00192 (boot.go:16) PCDATA $2, $0
0x00c0 00192 (boot.go:16) MOVQ CX, 16(SP)
0x00c5 00197 (boot.go:16) MOVQ $1, 24(SP)
0x00ce 00206 (boot.go:16) MOVQ $1, 32(SP)
0x00d7 00215 (boot.go:16) CALL runtime.deferproc(SB)
0x00dc 00220 (boot.go:16) TESTL AX, AX
0x00de 00222 (boot.go:16) JNE 592
0x00e4 00228 (boot.go:17) PCDATA $2, $1
0x00e4 00228 (boot.go:17) MOVQ "".b+72(SP), AX
0x00e9 00233 (boot.go:17) PCDATA $2, $0
0x00e9 00233 (boot.go:17) MOVQ (AX), CX
0x00ec 00236 (boot.go:17) MOVQ CX, (SP)
0x00f0 00240 (boot.go:17) CALL runtime.convT64(SB)
0x00f5 00245 (boot.go:17) PCDATA $2, $1
0x00f5 00245 (boot.go:17) MOVQ 8(SP), AX
0x00fa 00250 (boot.go:17) PCDATA $0, $3
0x00fa 00250 (boot.go:17) XORPS X0, X0
0x00fd 00253 (boot.go:17) MOVUPS X0, ""..autotmp_15+112(SP)
0x0102 00258 (boot.go:17) PCDATA $2, $2
0x0102 00258 (boot.go:17) LEAQ type.int(SB), CX
0x0109 00265 (boot.go:17) PCDATA $2, $1
0x0109 00265 (boot.go:17) MOVQ CX, ""..autotmp_15+112(SP)
0x010e 00270 (boot.go:17) PCDATA $2, $0
0x010e 00270 (boot.go:17) MOVQ AX, ""..autotmp_15+120(SP)
0x0113 00275 (boot.go:17) MOVL $48, (SP)
0x011a 00282 (boot.go:17) PCDATA $2, $1
0x011a 00282 (boot.go:17) LEAQ fmt.Println·f(SB), AX
0x0121 00289 (boot.go:17) PCDATA $2, $0
0x0121 00289 (boot.go:17) MOVQ AX, 8(SP)
0x0126 00294 (boot.go:17) PCDATA $2, $4
0x0126 00294 (boot.go:17) PCDATA $0, $1
0x0126 00294 (boot.go:17) LEAQ ""..autotmp_15+112(SP), DX
0x012b 00299 (boot.go:17) PCDATA $2, $0
0x012b 00299 (boot.go:17) MOVQ DX, 16(SP)
0x0130 00304 (boot.go:17) MOVQ $1, 24(SP)
0x0139 00313 (boot.go:17) MOVQ $1, 32(SP)
0x0142 00322 (boot.go:17) CALL runtime.deferproc(SB)
0x0147 00327 (boot.go:17) TESTL AX, AX
0x0149 00329 (boot.go:17) JNE 570
0x014f 00335 (boot.go:18) MOVQ "".a+64(SP), AX
0x0154 00340 (boot.go:18) MOVQ AX, (SP)
0x0158 00344 (boot.go:18) CALL runtime.convT64(SB)
0x015d 00349 (boot.go:18) PCDATA $2, $1
0x015d 00349 (boot.go:18) MOVQ 8(SP), AX
0x0162 00354 (boot.go:18) PCDATA $0, $4
0x0162 00354 (boot.go:18) XORPS X0, X0
0x0165 00357 (boot.go:18) MOVUPS X0, ""..autotmp_20+96(SP)
0x016a 00362 (boot.go:18) PCDATA $2, $2
0x016a 00362 (boot.go:18) LEAQ type.int(SB), CX
0x0171 00369 (boot.go:18) PCDATA $2, $1
0x0171 00369 (boot.go:18) MOVQ CX, ""..autotmp_20+96(SP)
0x0176 00374 (boot.go:18) PCDATA $2, $0
0x0176 00374 (boot.go:18) MOVQ AX, ""..autotmp_20+104(SP)
0x017b 00379 (boot.go:18) MOVL $48, (SP)
0x0182 00386 (boot.go:18) PCDATA $2, $1
0x0182 00386 (boot.go:18) LEAQ fmt.Println·f(SB), AX
0x0189 00393 (boot.go:18) PCDATA $2, $0
0x0189 00393 (boot.go:18) MOVQ AX, 8(SP)
0x018e 00398 (boot.go:18) PCDATA $2, $1
0x018e 00398 (boot.go:18) PCDATA $0, $1
0x018e 00398 (boot.go:18) LEAQ ""..autotmp_20+96(SP), AX
0x0193 00403 (boot.go:18) PCDATA $2, $0
0x0193 00403 (boot.go:18) MOVQ AX, 16(SP)
0x0198 00408 (boot.go:18) MOVQ $1, 24(SP)
0x01a1 00417 (boot.go:18) MOVQ $1, 32(SP)
0x01aa 00426 (boot.go:18) CALL runtime.deferproc(SB)
0x01af 00431 (boot.go:18) TESTL AX, AX
0x01b1 00433 (boot.go:18) JNE 548
0x01b3 00435 (boot.go:20) MOVL $16, (SP)
0x01ba 00442 (boot.go:20) PCDATA $2, $1
0x01ba 00442 (boot.go:20) LEAQ "".main.func2·f(SB), AX
0x01c1 00449 (boot.go:20) PCDATA $2, $0
0x01c1 00449 (boot.go:20) MOVQ AX, 8(SP)
0x01c6 00454 (boot.go:20) MOVQ "".a+64(SP), AX
0x01cb 00459 (boot.go:20) MOVQ AX, 16(SP)
0x01d0 00464 (boot.go:20) PCDATA $2, $1
0x01d0 00464 (boot.go:20) MOVQ "".b+72(SP), AX
0x01d5 00469 (boot.go:20) PCDATA $2, $0
0x01d5 00469 (boot.go:20) MOVQ AX, 24(SP)
0x01da 00474 (boot.go:20) CALL runtime.deferproc(SB)
0x01df 00479 (boot.go:20) TESTL AX, AX
0x01e1 00481 (boot.go:20) JNE 526
0x01e3 00483 (boot.go:25) MOVQ $1, "".a+64(SP)
0x01ec 00492 (boot.go:26) PCDATA $2, $1
0x01ec 00492 (boot.go:26) PCDATA $0, $0
0x01ec 00492 (boot.go:26) MOVQ "".b+72(SP), AX
0x01f1 00497 (boot.go:26) PCDATA $2, $0
0x01f1 00497 (boot.go:26) MOVQ $2, (AX)
0x01f8 00504 (boot.go:27) XCHGL AX, AX
0x01f9 00505 (boot.go:27) CALL runtime.deferreturn(SB)
0x01fe 00510 (boot.go:27) MOVQ 128(SP), BP
0x0206 00518 (boot.go:27) ADDQ $136, SP
0x020d 00525 (boot.go:27) RET
0x020e 00526 (boot.go:20) XCHGL AX, AX
0x020f 00527 (boot.go:20) CALL runtime.deferreturn(SB)
0x0214 00532 (boot.go:20) MOVQ 128(SP), BP
0x021c 00540 (boot.go:20) ADDQ $136, SP
0x0223 00547 (boot.go:20) RET
0x0224 00548 (boot.go:18) XCHGL AX, AX
0x0225 00549 (boot.go:18) CALL runtime.deferreturn(SB)
0x022a 00554 (boot.go:18) MOVQ 128(SP), BP
0x0232 00562 (boot.go:18) ADDQ $136, SP
0x0239 00569 (boot.go:18) RET
0x023a 00570 (boot.go:17) XCHGL AX, AX
0x023b 00571 (boot.go:17) CALL runtime.deferreturn(SB)
0x0240 00576 (boot.go:17) MOVQ 128(SP), BP
0x0248 00584 (boot.go:17) ADDQ $136, SP
0x024f 00591 (boot.go:17) RET
0x0250 00592 (boot.go:16) XCHGL AX, AX
0x0251 00593 (boot.go:16) CALL runtime.deferreturn(SB)
0x0256 00598 (boot.go:16) MOVQ 128(SP), BP
0x025e 00606 (boot.go:16) ADDQ $136, SP
0x0265 00613 (boot.go:16) RET
0x0266 00614 (boot.go:10) XCHGL AX, AX
0x0267 00615 (boot.go:10) CALL runtime.deferreturn(SB)
0x026c 00620 (boot.go:10) MOVQ 128(SP), BP
0x0274 00628 (boot.go:10) ADDQ $136, SP
0x027b 00635 (boot.go:10) RET
0x027c 00636 (boot.go:10) NOP
0x027c 00636 (boot.go:5) PCDATA $0, $-1
0x027c 00636 (boot.go:5) PCDATA $2, $-1
0x027c 00636 (boot.go:5) CALL runtime.morestack_noctxt(SB)
0x0281 00641 (boot.go:5) JMP 0
有疑问加站长微信联系(非本文作者)