【问题标题】:Why can one not assign to arrays inside maps in Go?为什么不能在 Go 中分配给地图内的数组?
【发布时间】:2016-04-02 03:05:54
【问题描述】:

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

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)
}

为什么我不能修改位于地图内的数组的内容,即使它们在地图外是可变的?为什么这适用于切片?

【问题讨论】:

标签: arrays dictionary go


【解决方案1】:

对于地图,它的值是不可寻址的。也就是说,当你使用value type(Go 中的数组是value types)时,你不能使用++ 来寻址该值。

但是,如果你使用 reference type(在 Go 中切片是 reference types),你可以按照你在示例中已经提到的那样。

无论地图中使用何种类型,这都是正确的。

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

游乐场: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 在读取时慷慨地取消引用指针指向它的值,并在重新分配期间更新值。

【讨论】:

猜你喜欢
  • 2010-11-12
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 2017-03-28
相关资源
最近更新 更多