Types 为什么Go输入了nil?

Types 为什么Go输入了nil?,types,go,null,Types,Go,Null,为什么Go输入了nil?为了方便起见,它抛出一个显式的接口确认检查。非类型化的nil有什么问题?设计师想用类型化的nil解决什么问题?听起来你在问这个错误消息: 这张照片是: prog.go:17: use of untyped nil [process exited with non-zero status] 在这个例子中,程序应该打印“A”还是“B” 你必须帮助编译器做出决定。这样做的方法是指定n的类型 例如: 打印“A” 在其他语言中,如果n为nil或其等效值,则n.Foo()可能

为什么Go输入了
nil
?为了方便起见,它抛出一个显式的接口确认检查。非类型化的
nil
有什么问题?设计师想用类型化的
nil
解决什么问题?

听起来你在问这个错误消息:

这张照片是:

prog.go:17: use of untyped nil
 [process exited with non-zero status]
在这个例子中,程序应该打印“A”还是“B”

你必须帮助编译器做出决定。这样做的方法是指定
n
的类型

例如:

打印“A”


在其他语言中,如果
n
nil
或其等效值,则
n.Foo()
可能会立即崩溃。Go的语言设计者决定让您决定应该发生什么。如果访问指针时未检查
nil
,则会得到与其他语言相同的行为。

这是由于类型安全
nil
实际上是Go中未初始化变量的值。切片、贴图、函数、通道、指针和接口的
nil
值不是同一类型,也不可比较。有关更多详细信息,请参阅

编辑:正如正确的技术术语所指出的,这是该类型的:

当通过声明或调用make或new分配内存来存储值,并且没有提供显式初始化时,将为内存提供默认初始化。此类值的每个元素的类型都设置为零值:布尔值为false,整数为0,浮点值为0.0,“”字符串为“”,指针、函数、接口、切片、通道和映射为nil


还有一些关于nil接口和中错误的信息。

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拒绝使用需要显式类型规范的默认值。

如果没有键入nil,则不能使用带有
nil
值的短赋值语句
:=

a := nil // Error: use of untyped nil
b := error(nil) // OK
同样,它启用以下一个班轮:

result, err := "A good result", error(nil)
写这样的东西有时可能会带来一些便利


但是,请注意,
nil
不是关键字或文字,并且Go没有内置的或标准类型的nil值。类型化的nil仅作为以下其中一项的结果而存在:

  • 使用默认(“零值”)初始化声明可为零的类型化变量
  • nil
    (直接或间接)赋值给键入的值
  • nil
    标识符强制转换为类型(如上面的示例所示)


这里有一个关于键入nils和接口的微妙之处的剪辑:

除非您所指的错误消息是“与远程服务器通信时出错”。(这是我得到的),您可能希望在答案中直接包含更多信息,而不是通过链接。我在此要强调的是,在
nil
上调用类型化方法既有意义又有用。@KeithThompson说得不错。我也加入了代码。达斯汀,说得好。这与问题无关,但值得一提。谢谢你们两位!“实际上是未初始化变量的值”,从技术上讲,它被称为类型的“零值”。所有类型都有一个零值。变量不是未初始化的。@newacct我使用的是语言规范()中的术语,其中声明“未初始化切片的值为
nil
”,“未初始化指针的值为
nil
”等。从同一文档中,我可以看出“零值”是正确的对于我在回答中提到的所有类型,都是
nil
。我认为“零值”的松散、不精确的定义是“未初始化的”,因为Go作者似乎很乐意在实际规范中使用这两种定义。我已经更新了我的答案,感谢正确的术语。如果Go使用显式键入的nil(如Swift
Optional
)可能更好,在这里找到一些推理和解释:这个答案听起来很正确。不知道为什么会被否决。
a := nil // Error: use of untyped nil
b := error(nil) // OK
result, err := "A good result", error(nil)