为什么在 golang 中打印 (nil) 地图会产生非“<nil>”结果?

jay*_*100 5 null dictionary go

在 golang 中,如果您创建一个带有未初始化映射的结构,则打印映射会产生一个非<nil>字符串。

为什么“打印”一个 nil 地图输出“map[]”而不是<nil>

// Assume above there is a struct, a.AA, which is created but which otherwise
// has not created the map.
//output:
//map[]
//map[]
fmt.Println(a.AA)
fmt.Println(make(map[string]int64))
Run Code Online (Sandbox Code Playgroud)

Kav*_*ian 6

这只是为了把事情说清楚。如果您运行此代码:

var m map[string]int64
log.Println(m == nil)
log.Printf("%T\n", m)
Run Code Online (Sandbox Code Playgroud)

它将打印:

$ true
$ map[string]int64
Run Code Online (Sandbox Code Playgroud)

m实际上nil此时也是如此。值nil也可以有类型,格式化程序使用该类型在可能的情况下打印出有意义的内容。

A 的map行为类似于其他语言中的引用类型。在 Go 中,即使结构的值为 ,您也可以调用该结构的方法nil

因此,即使对于您自己的结构,您也可以通过在结构上定义方法来实现 接口,并且每当您的结构的值为 时,您都可以打印出比 更合适的内容。具有:fmt.StringerString() stringnil<nil>

type someData struct {
    someValue string
}

func (x *someData) String() string {
    if x == nil {
        return "NO PROPER DATA HERE!"
    }

    return x.someValue
}
Run Code Online (Sandbox Code Playgroud)

那么如果我们运行:

var data *someData
log.Println(data)
data = new(someData)
data.someValue = "Aloha! :)"
log.Println(data)
Run Code Online (Sandbox Code Playgroud)

输出将是:

$ NO PROPER DATA HERE!
$ Aloha! :)
Run Code Online (Sandbox Code Playgroud)

<nil>请参阅第一行,尽管我们的结构指针位于nil该点,但我们没有得到输出。


Jac*_*cik 0

nil 指针与空(或零)映射不同。有关零值的权威信息,请参阅https://golang.org/ref/spec#The_zero_value 。

如果你想要一个 nil,你需要一个指针,如下所示:

package main

import (
    "fmt"
)

func main() {
    var myMap map[string]int64
    fmt.Printf("myMap before assignment: %v\n", myMap)

    myMap = make(map[string]int64)
    fmt.Printf("myMap after assignment : %v\n", myMap)

    var myMapPointer *map[string]int64
    fmt.Printf("myMapPointer before assignment: %v\n", myMapPointer)

    myMapPointer = new(map[string]int64)
    fmt.Printf("myMapPointer after assignment : %v\n", myMapPointer)
}
Run Code Online (Sandbox Code Playgroud)

这给出:

myMap before assignment: map[]
myMap after assignment : map[]
myMapPointer before assignment: <nil>
myMapPointer after assignment : &map[]
Run Code Online (Sandbox Code Playgroud)