原视频: 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 mainfunc 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]}