arrays - 为什么不能在 Go 中分配给 map 内的数组?

标签 arrays dictionary go

这里有一个简短的例子来演示:

package main

import "fmt"

func main() {
    array := [3]int{1, 2, 3}
    array[0]++ // Works
    slice := make([]int, 3)
    for i := range slice {
        slice[i] = i + 1
    }
    arrayMap := make(map[int][3]int)
    sliceMap := make(map[int][]int)
    arrayMap[0] = array
    sliceMap[0] = slice
    //arrayMap[0][0]++ // Does not compile: "cannot assign to arrayMap[0][0]"
    sliceMap[0][0]++
    fmt.Println(arrayMap)
    fmt.Println(sliceMap)
}

如果数组在 map 内,为什么我不能修改数组的内容,即使它们在 map 外是可变的?为什么这适用于 slice ?

最佳答案

对于 map 来说,它的值是不可寻址的。也就是说,当您使用值类型(数组在 Go 中是值类型)时,您不能使用++ 来寻址该值。

但是,如果您使用引用类型( slice 在 Go 中是引用类型),您可以像示例中提到的那样。

无论 map 中使用的类型如何,这都适用。

我们可以做的一件事是使用类型的 ptr 地址。例如,如果您获取数组的地址,那么它应该可以工作:

Playground :http://play.golang.org/p/XeIThVewWD

package main

import "fmt"

func main() {
    array := [3]int{1, 2, 3}
    slice := []int{1, 2, 3}

    arrayMap := make(map[int]*[3]int) // use the pointer to the type
    sliceMap := make(map[int][]int)
    arrayMap[0] = &array // get the pointer to the type
    sliceMap[0] = slice

    arrayMap[0][0]++ // works, because it's a pointer to the array
    sliceMap[0][0]++

    fmt.Println(*arrayMap[0])
    fmt.Println(sliceMap[0])
}

// outputs
[2 2 3]
[2 2 3]

这有效并将 array[0] 索引递增到 2,如预期的那样。

它之所以有效,是因为 Go 在读取时亲切地取消引用指向它的值的指针,并在重新分配期间更新该值。

关于arrays - 为什么不能在 Go 中分配给 map 内的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36368704/

相关文章:

python - Python中的Dict.get是用来比较字典中的键吗?

windows - Golang httpClient CA证书默认位置?

xml - 获取 xml 节点属性的值

java - 如何将数组的值放入另一个数组?

c - typedef 在字符数组方面的使用

python - 锁定自定义词典

c# - 根据键对字典进行就地排序

go - 转到Buffalo : ERRO[0000] Error: name buffalodevn is not allowed,尝试使用其他应用程序名称

c - C 中的指针和段错误

javascript - 如何使用 for 循环和拼接来删除单词,然后检查数组中的特定单词