Go为什么键入nil?

Eon*_*nil 27 null types go

为什么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,则会获得与其他语言相同的行为.

  • 除非您所指的错误消息是"与远程服务器通信时出错".(这就是我得到的),您可能希望直接在答案中包含更多信息,而不是通过链接. (2认同)

Int*_*net 13

这是由于类型安全.nil实际上是Go 中未初始化变量的值.的nil用于切片,地图功能,通道指针和接口值不相同的类型,并且不具有可比性.有关详细信息,请参阅语言规范.

编辑:正如@newacct指出的那样,正确的技术术语是该类型的"零值":

当分配内存来存储值时,无论是通过声明还是调用make或new,并且没有提供显式初始化,内存都会被赋予默认初始化.这种值的每个元素都设置为其类型的零值:布尔值为false,整数为0,浮点数为0.0,字符串为"",指针,函数,接口,切片,通道和映射为nil.

游乐场的例子

还有一些关于nil接口和错误的信息为什么我的nil错误值不等于nil?在Go FAQ中.

  • "实际上是未初始化变量的值"从技术上讲,它被称为类型的"零值".所有类型都具有零值.变量不是未初始化的. (2认同)

Kon*_*ski 5

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 拒绝这需要明确的类型规范。


nob*_*bar 5

如果没有 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?