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

In golang, if you create a struct with a map in it, which is uninitialized, printing the map yields a non <nil> string.

Why does "print" of a nil map output "map[]" instead of <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))

A nil pointer is not the same as an empty (or zero) map. See https://golang.org/ref/spec#The_zero_value for authoritative information concerning zero values.

If you want a nil, you need a pointer, such as in the following example:

package main

import (
    "fmt"
)

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

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

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

    myMapPointer = new(map[string]int64)
    fmt.Printf("myMapPointer after assignment : %v
", myMapPointer)
}

This gives:

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

It's just for making things clear. If you run this code:

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

It will print:

$ true
$ map[string]int64

So m is actually nil at this point. A nil value (can) have a type too and the formater uses that to print out something meaningful when possible.

A map is a reference type. And in Go you can call methods of a struct even if it's value is nil.

So even for your own structs, you can implement fmt.Stringer interface by just defining the String() string method on your struct and whenever your struct's value is nil you can print out something more proper than <nil>. Having:

type someData struct {
    someValue string
}

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

    return x.someValue
}

Then if we run:

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

The output will be:

$ NO PROPER DATA HERE!
$ Aloha! :)

See at the first line we did not get <nil> as output, despite the fact that our struct pointer is nil at that point.