为什么地图上没有按键

时间:2018-10-25 21:16:48

标签: dictionary go

我创建了一张地图:

l := make(map[*A]string)

其中A是:

type A struct{}

然后在其中添加键值:

a1 := &A{}
a2 := &A{}
a3 := &A{}

l[a1] = "a1"
l[a2] = "a2"
l[a3] = "a3"

我希望在进行range时会看到所有值(“ a1”,“ a2”,“ a3”)

for k, v := range l{
    fmt.Println(k, v)
}

但是我只看到最后一个。

为什么会这样? https://play.golang.org/p/GSdUWzExxLK

2 个答案:

答案 0 :(得分:8)

因为您的结构没有字段,所以Go会将指向它的所有指针优化到相同的地址,因此您每次都使用相同的键。给struct一个字段(即使您从未在其中输入值),也将得到预期的行为。

游乐场:https://play.golang.org/p/n-WUZ9wqpGJ

您可以了解有关空结构(包括此指针行为)on Dave Cheney's blog的更多信息。

在规范中Sizes and Alignments下仅作了简要提及,实际上是规范中的最后一句话:

  

如果结构或数组类型不包含大小大于零的字段(或元素),则其大小为零。两个不同的零大小变量在内存中可能具有相同的地址。

答案 1 :(得分:1)

这是因为A是一个空结构。由于它无法更改,因此始终为其分配相同的内存地址。如果您将字段添加到A,它将开始工作:

type A struct{a string}

func main() {
    a1 := A{}
    a2 := A{}

    l := make(map[*A]string)
    l[&a1] = "a1"
    l[&a2] = "a2"

    for i, v := range l{
        i := i
        fmt.Println(&i, v)
    }
}

打印:

0x40e138 a1
0x40e150 a2

https://play.golang.org/p/hYzU73kbVPV

戴夫·切尼(Dave Cheney)在这里更深入:

https://dave.cheney.net/2014/03/25/the-empty-struct