Golang:将键从地图附加到切片切片

我遇到了这个简单的Golang代码,并对Go在这里的行为感到惊讶。有人可以解释这里发生了什么,以及如何正确编写以下代码吗?


如您所见,我有一个 ,其中键是 的 。我添加几个值,然后循环访问 ,将每个键转换为 a 并将每个键附加到类型的对象。maparrayintmapslice[][]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


慕婉清6462132
浏览 153回答 3
3回答

狐的传说

在 for 循环中,循环变量在每次迭代时都会被覆盖。也就是说,是一个数组,对于每次迭代,都会用映射中的下一项覆盖 的内容。由于您添加了切片(只是数组上的视图),因此所有切片都作为后备数组,并且它们都具有相同的内容,即无论最后迭代的元素是什么。valvalval要修复,请复制阵列:    for val := range myMap {        val:=val        array = append(array, val[:])    }

RISEBY

您每次都会追加循环迭代器变量,该变量在每次迭代时都会更新。您需要改为追加本地范围的副本:for val := range myMap {    v := val    array = append(array, v[:])}

拉莫斯之舞

根据 Adrian 的建议,使用简单的程序重新创建代码,如下所示:package mainimport (    "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]]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go