這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
21.編譯執行下面代碼會出現什麼?
package mainvar( size :=1024 max_size = size*2)func main() { println(size,max_size)}
解析
考點:變數簡短模式
變數簡短模式限制:
- 定義變數同時顯式初始化
- 不能提供資料類型
- 只能在函數內部使用
結果:
syntax error: unexpected :=
22.下面函數有什麼問題?
package mainconst cl = 100var bl = 123func main() { println(&bl,bl) println(&cl,cl)}
解析
考點:常量
常量不同於變數的在運行期分配記憶體,常量通常會被編譯器在預先處理階段直接展開,作為指令資料使用,
cannot take the address of cl
23.編譯執行下面代碼會出現什麼?
package mainfunc main() { for i:=0;i<10 ;i++ { loop: println(i) } goto loop}
解析
考點:goto
goto不能跳轉到其他函數或者內層代碼
goto loop jumps into block starting at
24.編譯執行下面代碼會出現什麼?
package mainimport "fmt"func main() { type MyInt1 int type MyInt2 = int var i int =9 var i1 MyInt1 = i var i2 MyInt2 = i fmt.Println(i1,i2)}
解析
考點:**Go 1.9 新特性 Type Alias **
基於一個類型建立一個新類型,稱之為defintion;基於一個類型建立一個別名,稱之為alias。MyInt1為稱之為defintion,雖然底層類型為int類型,但是不能直接賦值,需要強轉;MyInt2稱之為alias,可以直接賦值。
結果:
cannot use i (type int) as type MyInt1 in assignment
25.編譯執行下面代碼會出現什麼?
package mainimport "fmt"type User struct {}type MyUser1 Usertype MyUser2 = Userfunc (i MyUser1) m1(){ fmt.Println("MyUser1.m1")}func (i User) m2(){ fmt.Println("User.m2")}func main() { var i1 MyUser1 var i2 MyUser2 i1.m1() i2.m2()}
解析
考點:**Go 1.9 新特性 Type Alias **
因為MyUser2完全等價於User,所以具有其所有的方法,並且其中一個新增了方法,另外一個也會有。但是
i1.m2()
是不能執行的,因為MyUser1沒有定義該方法。結果:
MyUser1.m1User.m2
26.編譯執行下面代碼會出現什麼?
package mainimport "fmt"type T1 struct {}func (t T1) m1(){ fmt.Println("T1.m1")}type T2 = T1type MyStruct struct { T1 T2}func main() { my:=MyStruct{} my.m1()}
解析
考點:**Go 1.9 新特性 Type Alias **
是不能正常編譯的,異常:
ambiguous selector my.m1
結果不限於方法,欄位也也一樣;也不限於type alias,type defintion也是一樣的,只要有重複的方法、欄位,就會有這種提示,因為不知道該選擇哪個。改為:
my.T1.m1()my.T2.m1()
type alias的定義,本質上是一樣的類型,只是起了一個別名,源類型怎麼用,別名資料型別也怎麼用,保留源類型的所有方法、欄位等。
27.編譯執行下面代碼會出現什麼?
package mainimport ( "errors" "fmt")var ErrDidNotWork = errors.New("did not work")func DoTheThing(reallyDoIt bool) (err error) { if reallyDoIt { result, err := tryTheThing() if err != nil || result != "it worked" { err = ErrDidNotWork } } return err}func tryTheThing() (string,error) { return "",ErrDidNotWork}func main() { fmt.Println(DoTheThing(true)) fmt.Println(DoTheThing(false))}
解析
考點:變數範圍
因為 if 語句塊內的 err 變數會遮罩函數範圍內的 err 變數,結果:
<nil><nil>
改為:
func DoTheThing(reallyDoIt bool) (err error) { var result string if reallyDoIt { result, err = tryTheThing() if err != nil || result != "it worked" { err = ErrDidNotWork } } return err}
28.編譯執行下面代碼會出現什麼?
package mainfunc test() []func() { var funs []func() for i:=0;i<2 ;i++ { funs = append(funs, func() { println(&i,i) }) } return funs}func main(){ funs:=test() for _,f:=range funs{ f() }}
解析
考點:閉包延遲求值
for迴圈複用局部變數i,每一次放入匿名函數的應用都是想一個變數。結果:
0xc042046000 20xc042046000 2
如果想不一樣可以改為:
func test() []func() { var funs []func() for i:=0;i<2 ;i++ { x:=i funs = append(funs, func() { println(&x,x) }) } return funs}
29.編譯執行下面代碼會出現什麼?
package mainfunc test(x int) (func(),func()) { return func() { println(x) x+=10 }, func() { println(x) }}func main() { a,b:=test(100) a() b()}
解析
考點:閉包引用相同變數*
結果:
100110
30.編譯執行下面代碼會出現什麼?
package mainimport ( "fmt" "reflect")func main1() { defer func() { if err:=recover();err!=nil{ fmt.Println(err) }else { fmt.Println("fatal") } }() defer func() { panic("defer panic") }() panic("panic")}func main() { defer func() { if err:=recover();err!=nil{ fmt.Println("++++") f:=err.(func()string) fmt.Println(err,f(),reflect.TypeOf(err).Kind().String()) }else { fmt.Println("fatal") } }() defer func() { panic(func() string { return "defer panic" }) }() panic("panic")}
解析
考點:panic僅有最後一個可以被revover捕獲
觸發panic("panic")後順序執行defer,但是defer中還有一個panic,所以覆蓋了之前的panic("panic")
defer panic