提问人:loosebazooka 提问时间:7/17/2021 最后编辑:Jonathan Hallloosebazooka 更新时间:7/17/2021 访问量:261
从 map[string][]string 返回的空列表有什么特别之处
What's special about an empty list returned from a map[string][]string
问:
这是一个奇怪的情况,我不明白 Go 在做什么。我以一些代码结束,这些代码使用了尚未插入该键的 map 的默认值。
package main
import (
"fmt"
"reflect"
)
func main() {
mmm := map[string][]string{}
nnn := map[string][]string {
"a": {},
}
x := mmm["a"]
y := nnn["a"]
z := []string{}
fmt.Println(reflect.DeepEqual(x,y))
fmt.Println(reflect.DeepEqual(x,z))
fmt.Println(reflect.DeepEqual(y,z))
fmt.Printf("%T, %T, %T", x, y, z)
}
我得到意外的输出
false
false
true
[]string, []string, []string
我所期望的全面。执行此操作的地图的默认值是什么?true
答:
3赞
icza
7/17/2021
#1
如果添加其他打印行:
fmt.Printf("%#v, %#v, %#v", x, y, z)
一切都会变得清晰。它输出(在 Go Playground 上尝试):
[]string(nil), []string{}, []string{}
x
是一个切片存在,并且是具有长度的非切片,就像 一样。nil
y
nil
0
z
使用不在地图中的键为地图编制索引时,将导致地图值类型的值为零。在本例中,值类型为 ,它是切片类型,切片类型的零值为 。[]string
nil
并反思。DeepEqual()
记录了切片和非切片不相等:nil
nil
请注意,非 nil 空切片和 nil 切片(例如,[]byte{} 和 []byte(nil))并不相等。
2赞
Hymns For Disco
7/17/2021
#2
首先,只是一个快速的更正,这种数据类型被称为“切片”,而不是“列表”。
当您查找不存在的地图键时,您会得到地图值类型的“零值”。对于切片,零值是切片。切片的行为通常与空切片非常相似(例如,切片的为零),但它们不被视为相同。在 Go 中,切片实际上并没有定义相等性,因此需要反映。DeepEqual
来决定此处的平等含义。nil
nil
len
nil
您将在文档中看到以下说明,其中解释了此处的行为:
当满足以下所有条件时,切片值完全相等:它们都是 nil 或两个非 nil,它们具有相同的长度,并且它们指向同一基础数组的相同初始条目(即 &x[0] == &y[0])或它们的相应元素(直到长度)完全相等。请注意,非 nil 空切片和 nil 切片(例如,[]byte{} 和 []byte(nil))并不相等。
评论
0赞
loosebazooka
7/17/2021
是的,我习惯于用 java 思考
评论