共计 1933 个字符,预计需要花费 5 分钟才能阅读完成。
背景
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,零值是 nil
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。
知乎:无忌。
References
- https://twitter.com/val_delep…
- https://github.com/jincheng9/…