Golang

  1. 以下代码的输出内容
 1package main
 2import (
 3	"fmt"
 4)
 5
 6func main() {
 7	deferCall()
 8}
 9func deferCall() {
10	defer func() { fmt.Println(">>> before") }()
11	defer func() { fmt.Println(">>> in process") }()
12	defer func() { fmt.Println(">>> done") }()
13	panic("<<< panic here")
14}

输出结果如下

1>>> done
2>>> in process
3>>> before
4panic: <<< panic here

defer执行的顺序是后进先出, 压栈。当出现panic的时候,会按照defer的后进先出的顺序执行,最后才会执行panic。

defer是一个压栈过程。

  1. 这段代码的输出,以及原因
 1package main
 2
 3import "fmt"
 4
 5func main() {
 6	slice := []int{0, 1, 2, 3}
 7	m := make(map[int]*int)
 8
 9	for key, val := range slice {
10		m[key] = &val
11	}
12
13	for k, v := range m {
14		fmt.Println(k, "->", *v)
15	}
16}

结果输出如下

10 -> 3
21 -> 3
32 -> 3
43 -> 3

for range 循环中的key & val 只会初始化一次。

所有的m[key]的取值都为变量val的地址,val 最后被赋值为3。

如果把fmt.Println(k, "->", *v) 修改为fmt.Println(k, "->", v) 结果如下, 所有的m[key]都指向了同一地址

10 -> 0xc0000b4008
21 -> 0xc0000b4008
32 -> 0xc0000b4008
43 -> 0xc0000b4008