乐趣区

关于golang:70-Go-中不常注意的各种细节集锦-Go-夜读

原视频: 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]
}
退出移动版