英文:
Adding arrays (from a map) to a slice of slices in Go
问题
我有一个带有数组键的地图。
我想将所有的键/数组添加到一个切片的切片中。
然而,我得到了意外的结果。
代码:
package main
import "fmt"
func main() {
var finalResult [][]int
set := make(map[[2]int]int)
a, b, c := [2]int{1, 1}, [2]int{2, 2}, [2]int{3, 3}
set[a], set[b], set[c] = 1, 1, 1
fmt.Println("set: ", set)
for x := range set {
fmt.Println("\nfinalResult 0: ", finalResult)
fmt.Println("x: ", x[:])
finalResult = append(finalResult, x[:])
fmt.Println("finalResult 1: ", finalResult)
}
}
输出:
set: map[[1 1]:1 [2 2]:1 [3 3]:1]
finalResult 0: []
x: [1 1]
finalResult 1: [[1 1]]
finalResult 0: [[2 2]]
x: [2 2]
finalResult 1: [[2 2] [2 2]]
finalResult 0: [[3 3] [3 3]]
x: [3 3]
finalResult 1: [[3 3] [3 3] [3 3]]
在for循环中,finalResult似乎在改变?
有人能解释发生了什么以及如何解决这个问题吗?
英文:
I have a map with arrays for keys.
I want to add all of the keys/arrays to a slice of slices.
However, I am getting unexpected results.
Code:
package main
import "fmt"
func main() {
var finalResult [][]int
set := make(map[[2]int]int)
a, b, c := [2]int{1, 1}, [2]int{2, 2}, [2]int{3, 3}
set[a], set[b], set[c] = 1, 1, 1
fmt.Println("set: ", set)
for x := range set {
fmt.Println("\nfinalResult 0: ", finalResult)
fmt.Println("x: ", x[:])
finalResult = append(finalResult, x[:])
fmt.Println("finalResult 1: ", finalResult)
}
}
Output:
set: map[[1 1]:1 [2 2]:1 [3 3]:1]
finalResult 0: []
x: [1 1]
finalResult 1: [[1 1]]
finalResult 0: [[2 2]]
x: [2 2]
finalResult 1: [[2 2] [2 2]]
finalResult 0: [[3 3] [3 3]]
x: [3 3]
finalResult 1: [[3 3] [3 3] [3 3]]
finalResult appears to be changing during the for loop?
Can someone explain what is happening and how I can work around this issue?
答案1
得分: 2
问题是,你将x
局部变量附加到指针finalResult
上,所以在每次循环中,x
将指向内存中的一个新数组。当你将这个x
三次添加到finalResult
并打印它时,所有三个x
都将指向相同的内存地址。你需要在每次循环中将x
指向的内容复制到一个新变量中,并将其添加到finalResult
中。
package main
import "fmt"
func main() {
var finalResult [][]int
set := make(map[[2]int]int)
a, b, c := [2]int{1, 1}, [2]int{2, 2}, [2]int{3, 3}
set[a], set[b], set[c] = 1, 1, 1
fmt.Println("set: ", set)
for x := range set {
fmt.Println("\nfinalResult 0: ", finalResult)
fmt.Println("x: ", x[:])
a := make([]int, 2)
copy(a, x[:])
finalResult = append(finalResult, a)
fmt.Println("finalResult 1: ", finalResult)
}
}
但要注意,遍历映射将始终是随机顺序的,所以你的最终结果可能在每次运行时都会改变。
英文:
The problem is, that you append the x
local variable to the finalResult
, which is a pointer, so in every for loop, the x
will point to a new array in the memory. When you add this x
three times to the finalResult and print it, all the three x
will be points to the same memory address. You have to copy the content where x
points in every loop to a new variable and add this to the finalResult.
package main
import "fmt"
func main() {
var finalResult [][]int
set := make(map[[2]int]int)
a, b, c := [2]int{1, 1}, [2]int{2, 2}, [2]int{3, 3}
set[a], set[b], set[c] = 1, 1, 1
fmt.Println("set: ", set)
for x := range set {
fmt.Println("\nfinalResult 0: ", finalResult)
fmt.Println("x: ", x[:])
a := make([]int, 2)
copy(a, x[:])
finalResult = append(finalResult, a)
fmt.Println("finalResult 1: ", finalResult)
}
}
But be aware, that ranging over a map will be always in random order, so your final result may change on every run.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论