背景
Google工程師Valentin Deleplace出了1道關於變數初始化的題目,本來以為很簡單,沒想到回答正確率不到30%,拿出來和大家分享下。
題目
// quiz.go
package main
import "fmt"
func main() {
var a *int
*a = 5.0
fmt.Println(*a)
}
- A:
5
- B:
5.0
- C:
panic
- D: 編譯錯誤
解析
這道題主要考察2個知識點:
- 變數零值。題目中
a
是一個指標型別的變數,var a *int
這行程式碼沒有對變數a
初始化賦值,所以變數a
的值是零值,指標的零值是nil
,所以a
的值是nil
。 變數初始化賦值。如果對
int
型別的變數賦值為浮點數5.0
是合法的,因為5.0
是untyped float constant,是可以在不損失精度的情況下轉換為5
的。如果是賦值為5.1
那就非法了,因為要損失小數點後面的精度,編譯報錯如下:./quiz1.go:8:7: cannot use 5.1 (untyped float constant) as int value in assignment (truncated)
所以本題答案是C
,編譯的時候不會報錯,但是執行的時候因為a
的值是nil
,對nil
做*
操作就會引發panic,具體panic內容為:panic: runtime error: invalid memory address or nil pointer dereference
。
思考題
題目1:
// quiz1.go
package main
import "fmt"
func main() {
var a *int = new(int)
*a = 5.0
fmt.Println(*a)
}
題目2:
// quiz2.go
package main
import "fmt"
func main() {
var a *int = new(int)
var b float32 = 5.0
*a = b
fmt.Println(*a)
}
題目3:
// quiz3.go
package main
import "fmt"
func main() {
var a *int = new(int)
*a = 5.1
fmt.Println(*a)
}
想知道答案的可以給公眾號傳送訊息init
獲取答案。
總結
Go語言裡不同型別的變數的零值不一樣,給大家總結了各個型別的變數的零值:
數值:所有數值型別的零值都是0
- 整數,零值是0。byte, rune, uintptr也是整數型別,所以零值也是0。
- 浮點數,零值是0
- 複數,零值是0+0i
- 整數型別的變數是可以用
untyped float constant
進行賦值的,只要不損失精度即可。
- bool,零值是false
- 字串,零值是空串""
指標:var a *int,零值是nil
num := 100 var a * int = &num
切片:var a []int,零值是nil
var a []int = []int{1,2} list := [6]int{1,2} //size為6的陣列,前面2個元素是1和2,後面的是預設值0
map:var a map[string] int,零值是nil
dict := map[string] int{"a":1, "b":2}
函式:var a func(string) int,零值是nil
function := func(str string) string { return str } result := function("hello fans") fmt.Println("result=", result)
結構體: var instance Struct,結構體裡每個field的零值是對應型別的零值
type Circle struct { redius float64 } var c1 Circle c1.radius = 10.00
channel:var a chan int,通道channel,零值是nil
var a chan int = make(chan int) var b = make(chan string) c := make(chan bool)
介面:var a interface_type,介面interface,零值是nil
type Animal interface { speak() } type Cat struct { name string age int } func(cat Cat) speak() { fmt.Println("miao...") } // 定義一個介面變數a var a Animal = Cat{"gaffe", 1} a.speak() // miao...
開源地址
文章和示例程式碼開源在GitHub: Go語言初級、中級和高階教程。
公眾號:coding進階。關注公眾號可以獲取最新Go面試題和技術棧。
個人網站:Jincheng's Blog。
知乎:無忌。