为什么Go语言中的字符串不能为零?

blpfk2vs  于 2022-12-25  发布在  Go
关注(0)|答案(4)|浏览(235)

程序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

0wi1tuuw

0wi1tuuw1#

简单的答案是nil没有定义为language specificationstring类型的有效值。

......但也许你想要一个更长的答案?
nil是指针、接口、通道、切片、Map和函数类型的零值,并且它表示 * 未初始化 * 状态。
请考虑以下变量声明:

var a *SomeType
var b interface{}
var c func()

所有这些变量都有一个表示未初始化状态的值似乎是很自然的。a已经被声明为指针,但是当我们还没有将它指向任何东西时,它会指向什么呢?nil对于这些类型来说显然是零值。
至于通道、切片和Map,它们的零值是nil,原因很简单,它们的 * 实现 * 是这样的,它们必须在使用之前显式初始化,这主要是出于性能原因,这些类型都在内部表示为或多或少复杂的数据结构,初始化它们不是免费的。
然而,string不需要初始化,而且新字符串变量的默认零值是空字符串"",这似乎是很自然的,因此nil没有理由是有效的字符串值,将其添加到规范中只会使语言更加复杂,使用起来更加麻烦。
此外,string * 类型的nil代表什么?空字符串?我们已经有了。未初始化的字符串?没有这样的东西。

tcomlyy6

tcomlyy62#

在Go语言中,string是一种数据类型,而不是像C/C++中那样是指向数组的指针,因此不能将其赋值为nil。

bvk5enib

bvk5enib3#

因为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

jbose2ul

jbose2ul4#

Aedolon提出了一些很好的观点,但是更进一步,在其他语言中,字符串是将字节数组表示为字符的方便方法。我们需要做很多这件事,所以数组的这个特定用例得到了很多语言支持,使其更容易使用。然而,问题的核心是,您正在使用一个数组,因为它是一种引用类型,所以在一种语言中通常可以为空。也就是说,字符串不是真的空,指向数组的指针是空的。因为许多语言把这两件事混为一谈,程序员习惯于在使用字符串之前检查它是否为空。
Go语言不会这样做,字符串不能为空,因为Go语言的数据结构不允许这样做,你可以让一个指向字节数组的指针为空,但那不是字符串。

相关问题