为什么Go 打字 nil?为方便起见,它会抛出一个显式的接口验证检查.什么是无类型的问题nil以及设计师想要用打字解决的问题是什么nil?
Sea*_*ean 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()
}
Run Code Online (Sandbox Code Playgroud)
这打印:
prog.go:17: use of untyped nil
[process exited with non-zero status]
Run Code Online (Sandbox Code Playgroud)
在该示例中,程序是否应打印"A"或"B"?
你必须帮助编译器决定.你这样做的方法是指定类型n.
例如:
http://play.golang.org/p/zMxUFYgxpy
func main() {
var n *A
n.Foo()
}
Run Code Online (Sandbox Code Playgroud)
打印"A".
在其他语言中,n.Foo()如果n是nil或等效,可能会立即崩溃.Go的语言设计师决定让你决定应该发生什么.如果在不检查的情况下访问指针nil,则会获得与其他语言相同的行为.
Int*_*net 13
这是由于类型安全.nil实际上是Go 中未初始化变量的值.的nil用于切片,地图功能,通道指针和接口值不相同的类型,并且不具有可比性.有关详细信息,请参阅语言规范.
编辑:正如@newacct指出的那样,正确的技术术语是该类型的"零值":
当分配内存来存储值时,无论是通过声明还是调用make或new,并且没有提供显式初始化,内存都会被赋予默认初始化.这种值的每个元素都设置为其类型的零值:布尔值为false,整数为0,浮点数为0.0,字符串为"",指针,函数,接口,切片,通道和映射为nil.
还有一些关于nil接口和错误的信息为什么我的nil错误值不等于nil?在Go FAQ中.
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
Run Code Online (Sandbox Code Playgroud)
对于几乎任何表达式,它的类型是明确的,因为需要在某处显式指定类型 - 或者在数字文字的情况下,在未指定时具有默认值。此规则的唯一例外是nil。
n := nil // var n ???
Run Code Online (Sandbox Code Playgroud)
nil 是以下的有效值。
当用户键入时,类型没有好的默认值nil,因此 Golang 拒绝这需要明确的类型规范。
如果没有 typed-nil,就不能使用:=带有nil值的短赋值语句。
a := nil // Error: use of untyped nil
b := error(nil) // OK
Run Code Online (Sandbox Code Playgroud)
同样,它可以实现以下单行:
result, err := "A good result", error(nil)
Run Code Online (Sandbox Code Playgroud)
编写类似上面的内容有时可能会提供一些便利。
但是请注意,这nil不是一个关键字或文字-与围棋并没有有一个内置的或标准的类型化零值。Typed-nil 仅作为以下之一的结果存在:
nil(直接或间接)给一个类型化的值nil标识符转换为类型(如上面的示例所示)。这是一个关于类型化 nils 和接口的微妙之处的剪辑:GopherCon 2015:Kevin Cantwell - What could Go Wrong?