为啥 Go 中的字符串不能为 nil?
Posted
技术标签:
【中文标题】为啥 Go 中的字符串不能为 nil?【英文标题】:Why can't a string be nil in Go?为什么 Go 中的字符串不能为 nil? 【发布时间】:2016-06-30 07:32:21 【问题描述】:程序available on The Go Playground读取
package main
import "fmt"
func main()
var name string = nil
fmt.Println(name)
并产生错误
prog.go:6: cannot use nil as type string in assignment
我了解""
is the "zero value" for strings。我不明白为什么我不能将nil
分配给我的string
。
【问题讨论】:
您也不能将nil
分配给int
s。为什么这会让你对字符串感到惊讶?
通过防止将 nil 分配给字符串,该语言消除了一类错误。注意string pointers 可以赋值为 nil。
不知道为什么这被否决了。对我来说似乎是一个非常合理的问题
【参考方案1】:
简单的答案是nil
没有定义为language specification 中string
类型的有效值。
...但也许您想要更长的答案?
nil
是指针、接口、通道、切片、映射和函数类型的零值,它表示 未初始化 状态。
考虑以下变量声明:
var a *SomeType
var b interface
var c func()
所有这些变量都有一个代表未初始化状态的值似乎很自然。 a
已被声明为指针,但是当我们还没有将它指向任何东西时,它会指向什么?对于这些类型,nil
显然是零值。
对于通道、切片和映射,它们的零值是nil
,原因很简单,因为它们的实现必须在使用前显式初始化。这主要是出于性能原因,这些类型在内部都表示为或多或少复杂的数据结构,并且初始化它们不是免费的。
但是,string
不需要初始化,而且新字符串变量的默认零值是空字符串""
似乎很自然。因此,nil
没有理由成为有效的字符串值,将其添加到规范只会使语言更复杂,使用起来也更麻烦。
此外,nil
类型的string
代表什么?一个空字符串?我们已经有了。未初始化的字符串?没有这种东西。
【讨论】:
提示:如果处理可选参数 - 但是,您可以将指针传递给您的字符串,并且指针可以为 nil :)(您也可以使用空字符串。) “否 字符串。”【参考方案2】:string
是一种数据类型,它不是指向 C/C++ 之类的数组的指针。因此,您不能将其分配给 nil。
【讨论】:
【参考方案3】:因为 Golang string
是只读的字节切片。
但是,指向字符串 (*string) 的指针可以为 nil:
var s *string
s = nil
readonly := "readonly"
s = &readonly
dereference := *s
https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html
【讨论】:
【参考方案4】:Aedolon 提出了一些好的观点,但更进一步,在其他语言中,字符串是将字节数组表示为字符的便捷方式。我们需要做很多事情,所以这个数组的特定用例获得了很多语言支持,使其更易于使用。但是,问题的核心是使用数组,因为它是一种引用类型,所以它在语言中通常可以为空。也就是说,字符串并不是真正的空值,指向数组的指针是空值。由于许多语言将这两者混为一谈,因此程序员习惯于在使用字符串之前检查字符串是否为空。
Go 不会这样做。字符串不能为 nil,因为 go 中的数据结构不允许它。您可以将指向保存字符表示形式的字节数组的指针设为 null,但这不是字符串。
【讨论】:
以上是关于为啥 Go 中的字符串不能为 nil?的主要内容,如果未能解决你的问题,请参考以下文章
Swift:String 不能为 nil,那为啥 stringByAddingPercentEncodingWithAllowedCharacters 可以为 nil? [复制]