golang当迭代map时,如何获取key作为指针?

时间:2017-09-23 07:44:44

标签: go

目前我正在存储一个地图,其中键是一个结构(MyIntC)。我想将地图中的所有关键字检索为切片。切片将是指向地图键的指针。这样就没有多个密钥的副本。

当我在这里尝试(https://play.golang.org/p/bclmCh_YV5)时,它无效。

切片中的所有元素都将指向迭代的最后一个map键元素。

为什么会这样?我怎么能克服这个?

注意:我怀疑它与Slice of structs vs a slice of pointers to structs非常相似,我总是使用本地变量地址。

感谢。

2 个答案:

答案 0 :(得分:2)

您对范围循环中与k相关的问题是正确的。 k是一个局部变量,在每次迭代中,您只需将相同的指针地址添加到slice

您始终可以使用指向MyIntC的指针作为地图键。

// ...
slice := make([]*MyIntC,0, 5)
// ...
mapInts := make(map[*MyIntC]string)
// ...
for k, _ := range mapInts {
   slice = append(slice, k)
}
// ...

工作示例:https://play.golang.org/p/Opd7RVywNa

答案 1 :(得分:0)

您无法获得地图键的地址。这是为了防止您修改键,因为这样做可能会影响值在地图内的位置。 此外,Go 还不允许 getting the address of a map value

注意将指针存储为映射键的“解决方案”,因为这样做的语义非常不同 - 指向键的指针的值将用于查找和唯一性,而不是本身的值。

type MyIntC struct {
   MyInt int
}

func main() {
  myInt5 := &MyIntC{MyInt: 50}

  mapInts := make(map[*MyIntC]string)
  mapInts[myInt5] = "something 50"

  _, found := mapInts[&MyIntC{MyInt: 50}]

  fmt.Println(found)
}

打印 false

有关详细信息,请参阅 Go Gotcha: Struct pointers as map keys

真正的解决方案是“接受它”,即接受这样一个事实,即在迭代地图时您将获得密钥的副本。毕竟,密钥应该简短且唯一,因此复制它们应该不是问题。