网上有文章把”_“忽略函数多个返回值中的某几个称为”匿名变量“(anonymous variable),这个说法欠妥。实际上在外网上搜索”Golang anonymous variable“是找不到文章的,”_“只是一个语法告诉编译器忽略掉对应的函数返回值不要报错,英文是”skipping return values“。这是在编译阶段完成的事情,并不会在运行时去实际赋值,所以不应该叫做变量。
示例如下:
example.go
package main
func add(k, m, t int8) (int8, int8, int8) {
return k + 1, m + 1, t + 1
}
func sub(r, s, q int8) (int8, int8) {
i, _, j := add(r, s, q)
return i, j
}
func main() {
i, j := sub(7, 9, 13)
_ = i
_ = j
}
编译成汇编:
GOOS=linux GOARCH=386 go tool compile -S example.go > example.S
example.S
sub函数部分:
"".sub STEXT size=46 args=0x8 locals=0x0
0x0000 00000 (example.go:7) TEXT "".sub(SB), ABIInternal, $0-8
0x0000 00000 (example.go:7) MOVL TLS, CX
0x0007 00007 (example.go:7) MOVL (CX)(TLS*2), CX
0x000d 00013 (example.go:7) CMPL SP, 8(CX)
0x0010 00016 (example.go:7) JLS 39
0x0012 00018 (example.go:7) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0012 00018 (example.go:7) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0012 00018 (example.go:7) FUNCDATA $2, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0012 00018 (example.go:8) PCDATA $0, $0
0x0012 00018 (example.go:8) PCDATA $1, $0
0x0012 00018 (<unknown line number>) NOP
0x0012 00018 (example.go:8) MOVBLZX "".r+4(SP), AX // r的值由+4(SP)move到AX
0x0017 00023 (example.go:4) INCL AX // AX自增
0x0018 00024 (example.go:9) MOVB AX, "".~r3+8(SP) //move AX的值到+8(SP)的栈空间准备返回
0x001c 00028 (example.go:4) MOVBLZX "".q+6(SP), AX // q的值由+6(SP)move到AX
0x0021 00033 (example.go:4) INCL AX // AX自增
0x0022 00034 (example.go:9) MOVB AX, "".~r4+9(SP) //move AX的值到+9(SP)的栈空间准备返回
0x0026 00038 (example.go:9) RET
0x0027 00039 (example.go:9) NOP
0x0027 00039 (example.go:7) PCDATA $1, $-1
0x0027 00039 (example.go:7) PCDATA $0, $-1
0x0027 00039 (example.go:7) CALL runtime.morestack_noctxt(SB)
0x002c 00044 (example.go:7) JMP 0
0x0000 65 8b 0d 00 00 00 00 8b 89 00 00 00 00 3b 61 08 e............;a.
0x0010 76 15 0f b6 44 24 04 40 88 44 24 08 0f b6 44 24 v...D$.@.D$...D$
0x0020 06 40 88 44 24 09 c3 e8 00 00 00 00 eb d2 .@.D$.........
rel 9+4 t=16 TLS+0
rel 40+4 t=8 runtime.morestack_noctxt+0
add作为小函数已经被编译到sub函数里了,sub函数编译成对r,q两个变量自增然后返回; 而“_”对应的第二个返回值在编译阶段被完全忽略了,完全没有对应的汇编代码。