【问题标题】: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 分配给ints。为什么这会让你对字符串感到惊讶?
  • 通过防止将 nil 分配给字符串,该语言消除了一类错误。注意string pointers 可以赋值为 nil。
  • 不知道为什么这被否决了。对我来说似乎是一个非常合理的问题

标签: go variable-assignment


【解决方案1】:

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

...但也许您想要更长的答案?

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,但这不是字符串。

      【讨论】:

        猜你喜欢
        • 2015-03-18
        • 2013-11-14
        • 2021-04-11
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        • 2018-10-26
        相关资源
        最近更新 更多