乐趣区

关于golang:Go-Quiz-从Go面试题看变量的零值和初始化赋值的注意事项

背景

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/…
退出移动版