英文:
Why does printing of a (nil) map in golang yield a non "<nil>" result?
问题
在Golang中,如果你创建了一个包含未初始化的映射的结构体,并打印该映射,输出的字符串将不是<nil>
,而是map[]
。
为什么打印一个空映射的结果是map[]
而不是<nil>
?
假设上面有一个结构体a
,其中包含一个名为AA
的映射,该映射已创建但未初始化。
输出结果为:
map[]
map[]
这是因为在Golang中,未初始化的映射被认为是一个空映射,而不是nil
。当你打印一个未初始化的映射时,它会显示为map[]
,表示一个空映射。要创建一个nil
映射,你需要使用var
关键字声明映射变量,并将其初始化为nil
。例如:
var m map[string]int
fmt.Println(m) // 输出: map[]
希望能帮到你!如果还有其他问题,请随时提问。
英文:
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))
答案1
得分: 6
这只是为了澄清事情。如果你运行这段代码:
var m map[string]int64
log.Println(m == nil)
log.Printf("%T\n", m)
它会打印出:
$ true
$ map[string]int64
所以在这一点上,m
实际上是 nil
。一个 nil
值也可以有一个类型,格式化器在可能的情况下使用它来打印出有意义的内容。
在其他语言中,map
的行为类似于引用类型。在 Go 中,即使值为 nil
,你也可以调用结构体的方法。
因此,即使对于你自己的结构体,你也可以通过在结构体上定义 String() string
方法来实现 fmt.Stringer
接口,并且当结构体的值为 nil
时,你可以打印出比 <nil>
更合适的内容。例如:
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! :)
请注意,在第一行,尽管我们的结构体指针在那一点上是 nil
,但我们没有得到 <nil>
作为输出。
英文:
It's just for making things clear. If you run this code:
var m map[string]int64
log.Println(m == nil)
log.Printf("%T\n", 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
behaves like a reference type in other languages. And in Go you can call methods of a struct even if its 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.
答案2
得分: 0
一个空指针不同于一个空(或零)映射。请参阅https://golang.org/ref/spec#The_zero_value以获取关于零值的权威信息。
如果你想要一个空指针,你需要一个指针,就像下面的示例中所示:
package main
import (
"fmt"
)
func main() {
var myMap map[string]int64
fmt.Printf("myMap赋值前:%v\n", myMap)
myMap = make(map[string]int64)
fmt.Printf("myMap赋值后:%v\n", myMap)
var myMapPointer *map[string]int64
fmt.Printf("myMapPointer赋值前:%v\n", myMapPointer)
myMapPointer = new(map[string]int64)
fmt.Printf("myMapPointer赋值后:%v\n", myMapPointer)
}
运行结果为:
myMap赋值前:map[]
myMap赋值后:map[]
myMapPointer赋值前:nil
myMapPointer赋值后:&map[]
英文:
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:
<!-- language: go -->
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)
}
This gives:
myMap before assignment: map[]
myMap after assignment : map[]
myMapPointer before assignment: <nil>
myMapPointer after assignment : &map[]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论