Golang:将地图中的键附加到切片中
Golang: Appending keys from a map to a slice of slices
我 运行 研究了这个简单的 Golang 代码,并对 Go 的行为感到惊讶。有人可以解释这里发生了什么,以及如何正确编写下面的代码吗?
如您所见,我有一个 map
,其中的键是 int
的 array
。我添加了几个值,然后遍历 map
,将每个键转换为 slice
并将每个键附加到 [][]int
.
类型的对象
func test() {
myMap := make(map[[3]int]bool)
myMap[[3]int{1, 2, 3}] = true
myMap[[3]int{0, 5, 4}] = true
myMap[[3]int{9, 7, 1}] = true
myMap[[3]int{0, 2, 8}] = true
array := [][]int{}
for val := range myMap {
array = append(array, val[:])
}
fmt.Println(array)
}
我期待最后一行打印 [[1,2,3], [0,5,4], [9,7,1], [0,2,8]]
,然而,令我惊讶的是它打印 [[0 2 8] [0 2 8] [0 2 8] [0 2 8]]
,或 [[9 7 1] [9 7 1] [9 7 1] [9 7 1]]
,或仅包含多个键之一的其他变体次。
我的go版本是1.16.5
在 for 循环中,循环变量在每次迭代时都会被覆盖。也就是说,val
是一个数组,对于每次迭代,val
的内容都会被映射中的下一项覆盖。由于您添加了切片(它们只是对数组的视图),因此所有切片都将 val
作为后备数组,并且它们都具有相同的内容,即迭代的最后一个元素。
要修复,请复制数组:
for val := range myMap {
val:=val
array = append(array, val[:])
}
您每次都附加循环迭代器变量,每次迭代都会更新。您需要附加一个本地范围的副本:
for val := range myMap {
v := val
array = append(array, v[:])
}
根据 Adrian 的建议,使用如下简单程序重新创建您的代码:
package main
import (
"fmt"
)
func main() {
test()
}
func test() {
myMap := make(map[[3]int]bool)
myMap[[3]int{1, 2, 3}] = true
myMap[[3]int{0, 5, 4}] = true
myMap[[3]int{9, 7, 1}] = true
myMap[[3]int{0, 2, 8}] = true
array := [][]int{}
for val := range myMap {
key := val
array = append(array, key[:])
}
fmt.Println(array)
}
输出:
[[1 2 3] [0 5 4] [9 7 1] [0 2 8]]
我 运行 研究了这个简单的 Golang 代码,并对 Go 的行为感到惊讶。有人可以解释这里发生了什么,以及如何正确编写下面的代码吗?
如您所见,我有一个 map
,其中的键是 int
的 array
。我添加了几个值,然后遍历 map
,将每个键转换为 slice
并将每个键附加到 [][]int
.
func test() {
myMap := make(map[[3]int]bool)
myMap[[3]int{1, 2, 3}] = true
myMap[[3]int{0, 5, 4}] = true
myMap[[3]int{9, 7, 1}] = true
myMap[[3]int{0, 2, 8}] = true
array := [][]int{}
for val := range myMap {
array = append(array, val[:])
}
fmt.Println(array)
}
我期待最后一行打印 [[1,2,3], [0,5,4], [9,7,1], [0,2,8]]
,然而,令我惊讶的是它打印 [[0 2 8] [0 2 8] [0 2 8] [0 2 8]]
,或 [[9 7 1] [9 7 1] [9 7 1] [9 7 1]]
,或仅包含多个键之一的其他变体次。
我的go版本是1.16.5
在 for 循环中,循环变量在每次迭代时都会被覆盖。也就是说,val
是一个数组,对于每次迭代,val
的内容都会被映射中的下一项覆盖。由于您添加了切片(它们只是对数组的视图),因此所有切片都将 val
作为后备数组,并且它们都具有相同的内容,即迭代的最后一个元素。
要修复,请复制数组:
for val := range myMap {
val:=val
array = append(array, val[:])
}
您每次都附加循环迭代器变量,每次迭代都会更新。您需要附加一个本地范围的副本:
for val := range myMap {
v := val
array = append(array, v[:])
}
根据 Adrian 的建议,使用如下简单程序重新创建您的代码:
package main
import (
"fmt"
)
func main() {
test()
}
func test() {
myMap := make(map[[3]int]bool)
myMap[[3]int{1, 2, 3}] = true
myMap[[3]int{0, 5, 4}] = true
myMap[[3]int{9, 7, 1}] = true
myMap[[3]int{0, 2, 8}] = true
array := [][]int{}
for val := range myMap {
key := val
array = append(array, key[:])
}
fmt.Println(array)
}
输出:
[[1 2 3] [0 5 4] [9 7 1] [0 2 8]]