从 map[string][]string 返回的空列表有什么特别之处
What's special about an empty list returned from a map[string][]string
这是一个奇怪的情况,我不明白 Go 在做什么。我以一些代码结束,这些代码使用了尚未插入该键的地图默认值。
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
全面。执行此操作的地图的默认值是什么?
如果再添加打印行:
fmt.Printf("%#v, %#v, %#v", x, y, z)
一切都会明朗的。它输出(在 Go Playground 上尝试):
[]string(nil), []string{}, []string{}
x
是 nil
的切片,而 y
是具有 0
长度的非 nil
切片,就像 z
.
使用不在地图中的键索引地图,会导致地图值类型为 zero value。在你的例子中,值类型是 []string
,它是一个切片类型,切片类型的零值是 nil
.
和 reflect.DeepEqual()
记录 nil
切片和非 nil
切片不相等:
Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.
首先,快速更正一下,这种数据类型称为“切片”,而不是“列表”。
当您查找不存在的地图键时,您会得到地图值类型的“零值”。在切片的情况下,零值是 nil
切片。 nil
切片的行为通常很像空切片(例如,nil
切片的 len
为零),但它们不被认为是相同的。在 Go 中实际上并没有为切片定义相等性,因此由 reflect.DeepEqual
决定这里的相等性意味着什么。
您将在解释此处行为的文档中看到这条注释:
Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.
这是一个奇怪的情况,我不明白 Go 在做什么。我以一些代码结束,这些代码使用了尚未插入该键的地图默认值。
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
全面。执行此操作的地图的默认值是什么?
如果再添加打印行:
fmt.Printf("%#v, %#v, %#v", x, y, z)
一切都会明朗的。它输出(在 Go Playground 上尝试):
[]string(nil), []string{}, []string{}
x
是 nil
的切片,而 y
是具有 0
长度的非 nil
切片,就像 z
.
使用不在地图中的键索引地图,会导致地图值类型为 zero value。在你的例子中,值类型是 []string
,它是一个切片类型,切片类型的零值是 nil
.
和 reflect.DeepEqual()
记录 nil
切片和非 nil
切片不相等:
Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.
首先,快速更正一下,这种数据类型称为“切片”,而不是“列表”。
当您查找不存在的地图键时,您会得到地图值类型的“零值”。在切片的情况下,零值是 nil
切片。 nil
切片的行为通常很像空切片(例如,nil
切片的 len
为零),但它们不被认为是相同的。在 Go 中实际上并没有为切片定义相等性,因此由 reflect.DeepEqual
决定这里的相等性意味着什么。
您将在解释此处行为的文档中看到这条注释:
Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.