【问题标题】:Why does printing of a (nil) map in golang yield a non "<nil>" result?为什么在 golang 中打印(nil)地图会产生非“<nil>”结果?
【发布时间】:2016-12-11 19:01:04
【问题描述】:

在 golang 中,如果您创建一个结构体,其中包含未初始化的映射,则打印映射会产生非 &lt;nil&gt; 字符串。

为什么 nil 映射的 "print" 输出 "map[]" 而不是 &lt;nil&gt;

// 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))

【问题讨论】:

  • 格式化程序就是这样打印的。这只是为了方便,所以显示类型很有用(更不用说你可以从 nil 映射索引)
  • @JimB 这就是答案,贴出来。

标签: dictionary go null


【解决方案1】:

这只是为了让事情变得清晰。如果你运行这段代码:

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

它将打印:

$ true
$ map[string]int64

所以m 在这一点上实际上是nilnil 值(可以)也有一个类型,并且格式化程序在可能的情况下使用它来打印出有意义的东西。

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

因此,即使对于您自己的结构,您也可以实现 fmt.Stringer 接口,只需在您的结构上定义String() string 方法,并且只要您的结构的值为nil,您就可以打印出更多内容比&lt;nil&gt; 合适。有:

type someData struct {
    someValue string
}

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

    return x.someValue
}

如果我们运行:

var data *someData
log.Println(data)
data = new(someData)
data.someValue = "Aloha! :)"
log.Println(data)

输出将是:

$ NO PROPER DATA HERE!
$ Aloha! :)

请看第一行我们没有得到&lt;nil&gt;作为输出,尽管我们的结构指针在那个时候是nil

【讨论】:

    【解决方案2】:

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

    如果你想要一个nil,你需要一个指针,比如下面的example

    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)
    }
    

    这给出了:

    myMap before assignment: map[]
    myMap after assignment : map[]
    myMapPointer before assignment: <nil>
    myMapPointer after assignment : &map[]
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多