一、以下代码的输出内容为
package main
import (
"fmt"
)
func main() {
defer_call()
}
func defer_call() {
defer func() { fmt.Println("打印前") }()
defer func() { fmt.Println("打印中") }()
defer func() { fmt.Println("打印后") }()
panic("触发异常")
}
答案
打印后
打印中
打印前
panic: 触发异常
解析
考查defer和panic组合的情况,在有panic时,会先执行defer然后再把恐慌传递出去。
二、以下代码有什么问题
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)
}
}
答案
key=zhou,value=&{wang 22}
key=li,value=&{wang 22}
key=wang,value=&{wang 22}
解析
for循环使用stu遍历时,stu只是一个临时变量,遍历过程中指针地址不变,所以后面的赋值都是指向了同一个内存区域,导致最后所有的信息都一致。
其实这个现象不仅仅存在于go
中,c/c++
和python
中也存在,原理也都一样。
修改方案
for i, _ := range stus {
stu:=stus[i]
m[stu.Name] = &stu
}
三、下面的代码会输出什么,并说明原因
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()
}
答案
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。
四、下面代码会输出什么
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()
}
答案
showA
showB
解析
go中没有继承,只有组合。Teacher中的People是一个匿名对象,通过它调用的函数都是自身的。
此处评论已关闭