从映射 [字符串][] 字符串返回的空列表有何特殊之处

这是一个奇怪的情况,我不明白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


红糖糍粑
浏览 64回答 2
2回答

慕的地10843

如果添加另一条打印线:fmt.Printf("%#v, %#v, %#v", x, y, z)一切都会变得清晰起来。它输出(在Go游乐场上尝试):[]string(nil), []string{}, []string{}x是一个切片,并且是具有长度的非切片,就像 。nilynil0z使用不在地图中的键对地图编制索引,将导致地图值类型的值为零。在你的例子中,值类型是 ,它是切片类型,切片类型的零值为 。[]stringnil并反思。DeepEqual() 文档切片和非切片不相等:nilnil请注意,非零空片和零片(例如,[]字节{}和[]字节(零))并不严重相等。

德玛西亚99

首先,只是快速更正,这种数据类型称为“切片”,而不是“列表”。查找不存在的映射键时,将获得映射值类型的“零值”。对于切片,零值是切片。切片通常表现得很像空切片(例如,切片的 为零),但它们不被视为相同。实际上,在 Go 中并没有为切片定义相等性,因此需要进行反思。Deep平等来决定平等在这里意味着什么。nilnillennil您将在文档中看到此注释,解释此处的行为:当以下所有情况都为真时,Slice 值深度相等:它们均为 nil 或均为非 nil,它们具有相同的长度,并且它们指向同一基础数组的相同初始条目(即 &x[0] == &y[0]),或者它们的相应元素(最大长度)深度相等。请注意,非零空片和零片(例如,[]字节{}和[]字节(零))并不严重相等。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go