为什么Go 键入 nil
?为方便起见,它会抛出一个显式的接口验证检查。无类型nil
的问题是什么?设计师想要用键入的nil
解决什么问题?
答案 0 :(得分:14)
听起来你在问这个错误信息:
http://play.golang.org/p/h80rmDYCTI
package main
import "fmt"
type A struct {}
type B struct {}
func (a *A) Foo() {
fmt.Println("A")
}
func (b *B) Foo() {
fmt.Println("B")
}
func main() {
n := nil
n.Foo()
}
打印:
prog.go:17: use of untyped nil
[process exited with non-zero status]
在该示例中,程序是否应打印“A”或“B”?
你必须帮助编译器决定。您这样做的方法是指定n
的类型。
例如:
http://play.golang.org/p/zMxUFYgxpy
func main() {
var n *A
n.Foo()
}
打印“A”。
在其他语言中,如果n.Foo()
为n
或等效,nil
可能会立即崩溃。 Go的语言设计师决定让你决定应该发生什么。如果在不检查nil
的情况下访问指针,则会获得与其他语言相同的行为。
答案 1 :(得分:12)
这是由于类型安全。 nil
实际上是Go中未初始化变量的值。切片,贴图,函数,通道,指针和接口的nil
值不是同一类型,并且不具有可比性。有关详细信息,请参阅The language spec。
编辑:正如@newacct指出的那样,对此类型的正确技术术语是"zero value":
当分配内存来存储值时,无论是通过声明还是调用make或new,并且没有提供显式初始化,内存都会被赋予默认初始化。这种值的每个元素都设置为其类型的零值:布尔值为false,整数为0,浮点数为0.0,字符串为“”,指针,函数,接口,切片,通道和映射为nil。 / p>
Why is my nil error value not equal to nil?中的Go FAQ还有一些关于nil接口和错误的信息。
答案 2 :(得分:1)
Golang中的所有变量都需要一个类型。使用:=
运算符从右侧表达式的类型推断出类型。
x := [0]int{} // var x [0]int
y := make(chan int) // var y chan int
z := map[int]int{} // var z map[int]int
a := func(int) {} // var a func(int)
b := 42 // var b int
c := 42.0 // var c float64
对于几乎任何表达式,其类型是明确的,因为需要在某处显式指定类型 - 或者在数字文字的情况下,在未指定时具有默认值。此规则的唯一例外是nil
。
n := nil // var n ???
nil
是以下内容的有效值。
当用户键入nil
时,类型没有良好的默认值,因此Golang拒绝这需要明确的类型规范。
答案 3 :(得分:0)
没有typed-nil,就不能使用带有:=
值的简短赋值语句nil
。
a := nil // Error: use of untyped nil
b := error(nil) // OK
同样,它启用以下单行代码:
result, err := "A good result", error(nil)
有时候写上面的东西可能会带来一些方便。
但是请注意,nil
不是关键字也不是字面量-Go的 not 没有内置的或标准的 typed-nil 值。 Typed-nil仅由于以下之一而存在:
nil
(直接或间接)分配给键入的值nil
标识符转换为一种类型(如上面的示例所示)。以下是有关带有类型化nil和接口的微妙内容的剪辑:GopherCon 2015: Kevin Cantwell - What Could Go Wrong?