一、以下代码的输出内容为
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package main import ( "fmt" ) func main() { defer_call() } func defer_call() { defer func() { fmt.Println("打印前") }() defer func() { fmt.Println("打印中") }() defer func() { fmt.Println("打印后") }() panic("触发异常") } |
答案
1 2 3 4 |
打印后 打印中 打印前 panic: 触发异常 |
解析
考查 defer 和 panic 组合的情况,在有 panic 时,会先执行 defer 然后再把恐慌传递出去。
更多相关内容可查看 defer 常见的坑以及官方文档描述。
二、以下代码有什么问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package main import ( "fmt" ) type student struct { Name string Age int } func pase_student() map[string]*student { m := make(map[string]*student) stus := []student{ {Name: "zhou", Age: 24}, {Name: "li", Age: 23}, {Name: "wang", Age: 22}, } for _, stu := range stus { m[stu.Name] = &stu } return m } func main() { students := pase_student() for k, v := range students { fmt.Printf("key=%s,value=%v \n", k, v) } } |
答案
1 2 3 |
key=zhou,value=&{wang 22} key=li,value=&{wang 22} key=wang,value=&{wang 22} |
解析
for 循环使用 stu 遍历时,stu 只是一个临时变量,遍历过程中指针地址不变,所以后面的赋值都是指向了同一个内存区域,导致最后所有的信息都一致。
其实这个现象不仅仅存在于 go
中,c/c++
和 python
中也存在,原理也都一样。
修改方案
1 2 3 4 |
for i, _ := range stus { stu:=stus[i] m[stu.Name] = &stu } |
三、下面的代码会输出什么,并说明原因
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package main import ( "sync" "fmt" ) func main() { wg := sync.WaitGroup{} wg.Add(21) for i := 0; i < 10; i++ { go func() { fmt.Println("i: ", i) wg.Done() }() } for j := 0; j < 10; j++ { go func(x int) { fmt.Println("j: ", x) wg.Done() }(j) } wg.Wait() } |
答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
j: 9 i: 10 j: 0 j: 1 j: 2 j: 3 j: 4 j: 5 j: 6 i: 10 i: 10 i: 10 i: 10 i: 10 j: 8 i: 10 i: 10 i: 10 j: 7 i: 10 |
解析
第一个循环中的打印是在函数中打印的,i 是外部的变量,执行 go func(){}
后代码不会立即执行,一般当该代码片段被调度器执行的时候,for 循环已经全部执行完毕,此时的 i 为 10 。所以 i 会打印 10 个 10,而 j 则会无序打印 1-10 。
四、下面代码会输出什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
type People struct{} func (p *People) ShowA() { fmt.Println("showA") p.ShowB() } func (p *People) ShowB() { fmt.Println("showB") } type Teacher struct { People } func (t *Teacher) ShowB() { fmt.Println("teacher showB") } func main() { t := Teacher{} t.ShowA() } |
答案
1 2 |
showA showB |
解析
go 中没有继承,只有组合。 Teacher 中的 People 是一个匿名对象,通过它调用的函数都是自身的。
评论