原视频: https://www.bilibili.com/vide…
1. 打印 true 还是 false?
func f() bool {return false}
func main() {switch f()
{
case true:
fmt.Println("true")
case false:
fmt.Println("false")
}
}
等价于
func f() bool {return false}
func main() {switch f();
false {
case true:
fmt.Println("true")
case false:
fmt.Println("false")
}
}
2. os.Exit(包含 log.Fatal 等)的时候不会调用 defer
3. runtime.Goexit 调用后会调用 defer
4. 估值后果因是否为变量或者常量而异
例 1:
func main() {
var n uint = 10
const N uint = 10
var x byte = (1 << n) / 100 // 1 被推断出 byte,溢出
var y byte = (1 << N) / 100 // 1 被推断不确定数
fmt.Println(x) // 0
fmt.Println(y) // 100
}
例 2:
func main() {
var n uint = 10
const N uint = 10
var x float64 = (1 << n) / 100 // 1 被推断出 float64,报错
var y float64 = (1 << N) / 100 // 1 被推断不确定数
fmt.Println(x)
fmt.Println(y)
}
例 2 编译报错
多值赋值
package main
func assign1() {
a, b := 1, 2
a, b = b, a
}
func assign2() {var a []int
a, a[0] = []int{2112321}, 212121
}
func main() {assign1()
assign2()}
执行后 go tool compile -N -l -S ./assignment.go > ./assignment.s
"".assign1 STEXT nosplit size=69 args=0x0 locals=0x20 funcid=0x0
0x0000 00000 (./assignment.go:3) TEXT "".assign1(SB), NOSPLIT|ABIInternal, $32-0
0x0000 00000 (./assignment.go:3) SUBQ $32, SP
0x0004 00004 (./assignment.go:3) MOVQ BP, 24(SP)
0x0009 00009 (./assignment.go:3) LEAQ 24(SP), BP
0x000e 00014 (./assignment.go:4) MOVQ $1, "".a+8(SP) // a = 1
0x0017 00023 (./assignment.go:4) MOVQ $2, "".b(SP) // b = 2
0x001f 00031 (./assignment.go:5) MOVQ "".a+8(SP), AX // AX = a = 1
0x0024 00036 (./assignment.go:5) MOVQ AX, ""..autotmp_2+16(SP) // autotmp_2 = AX = a = 1
0x0029 00041 (./assignment.go:5) MOVQ "".b(SP), AX // AX = b = 2
0x002d 00045 (./assignment.go:5) MOVQ AX, "".a+8(SP) // a = AX = 2
0x0032 00050 (./assignment.go:5) MOVQ ""..autotmp_2+16(SP), AX // AX = autotmp_2 = a = 1
0x0037 00055 (./assignment.go:5) MOVQ AX, "".b(SP) // b = AX
0x003b 00059 (./assignment.go:6) MOVQ 24(SP), BP
0x0040 00064 (./assignment.go:6) ADDQ $32, SP
0x0044 00068 (./assignment.go:6) RET H.. .
"".assign2 STEXT nosplit size=192 args=0x0 locals=0x70 funcid=0x0
0x0000 00000 (./assignment.go:8) TEXT "".assign2(SB), NOSPLIT|ABIInternal, $112-0
0x0000 00000 (./assignment.go:8) SUBQ $112, SP
0x0004 00004 (./assignment.go:8) MOVQ BP, 104(SP)
0x0009 00009 (./assignment.go:8) LEAQ 104(SP), BP
0x000e 00014 (./assignment.go:9) MOVQ $0, "".a+32(SP)
0x0017 00023 (./assignment.go:9) XORPS X0, X0
0x001a 00026 (./assignment.go:9) MOVUPS X0, "".a+40(SP) // a a []int = nil
0x001f 00031 (./assignment.go:10) MOVQ $0, ""..autotmp_4+16(SP)
0x0028 00040 (./assignment.go:10) LEAQ ""..autotmp_4+16(SP), DX
0x002d 00045 (./assignment.go:10) MOVQ DX, ""..autotmp_2+24(SP)
0x0032 00050 (./assignment.go:10) TESTB AL, (DX)
0x0034 00052 (./assignment.go:10) MOVQ $2112321, ""..autotmp_4+16(SP)
0x003d 00061 (./assignment.go:10) TESTB AL, (DX)
0x003f 00063 (./assignment.go:10) NOP
0x0040 00064 (./assignment.go:10) JMP 66
0x0042 00066 (./assignment.go:10) MOVQ DX, ""..autotmp_1+80(SP)
0x0047 00071 (./assignment.go:10) MOVQ $1, ""..autotmp_1+88(SP)
0x0050 00080 (./assignment.go:10) MOVQ $1, ""..autotmp_1+96(SP) // 00031-00080: autotmp_1 = []int{2112321}
0x0059 00089 (./assignment.go:10) MOVQ "".a+32(SP), DX
0x005e 00094 (./assignment.go:10) MOVQ "".a+40(SP), BX
0x0063 00099 (./assignment.go:10) MOVQ "".a+48(SP), SI
0x0068 00104 (./assignment.go:10) MOVQ DX, ""..autotmp_5+56(SP)
0x006d 00109 (./assignment.go:10) MOVQ BX, ""..autotmp_5+64(SP)
0x0072 00114 (./assignment.go:10) MOVQ SI, ""..autotmp_5+72(SP) // 00089-00114: autotmp_5 = copy(a)
0x0077 00119 (./assignment.go:10) MOVQ ""..autotmp_1+80(SP), DX
0x007c 00124 (./assignment.go:10) MOVQ ""..autotmp_1+88(SP), BX
0x0081 00129 (./assignment.go:10) MOVQ ""..autotmp_1+96(SP), SI
0x0086 00134 (./assignment.go:10) MOVQ DX, "".a+32(SP)
0x008b 00139 (./assignment.go:10) MOVQ BX, "".a+40(SP)
0x0090 00144 (./assignment.go:10) MOVQ SI, "".a+48(SP) // 00119-00144: a = autotmp_1
0x0095 00149 (./assignment.go:10) MOVQ ""..autotmp_5+64(SP), CX
0x009a 00154 (./assignment.go:10) MOVQ ""..autotmp_5+56(SP), DX
0x009f 00159 (./assignment.go:10) NOP
0x00a0 00160 (./assignment.go:10) TESTQ CX, CX // if CX != 0
0x00a3 00163 (./assignment.go:10) JHI 167 // CX != 0, 跳 167
0x00a5 00165 (./assignment.go:10) JMP 184 // CX == 0, 跳 184
0x00a7 00167 (./assignment.go:10) MOVQ $212121, (DX)
0x00ae 00174 (./assignment.go:11) MOVQ 104(SP), BP
0x00b3 00179 (./assignment.go:11) ADDQ $112, SP
0x00b7 00183 (./assignment.go:11) RET
0x00b8 00184 (./assignment.go:10) XORL AX, AX
0x00ba 00186 (./assignment.go:10) PCDATA $1, $0
0x00ba 00186 (./assignment.go:10) CALL runtime.panicIndex(SB)
0x00bf 00191 (./assignment.go:10) XCHGL AX, AX
所以最初 assign2 会抛异样
又例如:
func assign3() {var c = []int{1, 2, 3}
d := c
c, c[0] = []int{2112321}, 101
fmt.Println(c) // [2112321]
fmt.Println(d) // [101 2 3]
}