這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
一、以下代碼的輸出內容為
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() }
|
答案
解析
go中沒有繼承,只有組合。Teacher中的People是一個匿名對象,通過它調用的函數都是自身的。