Dictionary 插入地图时是否会进行(深度)复制关键点?

Dictionary 插入地图时是否会进行(深度)复制关键点?,dictionary,go,key,Dictionary,Go,Key,我有一张带有复杂键的地图——例如,2D数组: m := make(map[[2][3]int]int) 当我在地图中插入一把新钥匙时,Go是否会对钥匙进行深度复制 a := [2][3]int{{1, 2, 3}, {4, 5, 6}} m[a] = 1 换句话说,如果我在将数组a用作映射键后更改它,映射是否仍然包含a的旧值?数组总是按值传递,因此,在这种情况下,是的Go将生成键的深度副本 从 比较运算符==和!=必须为键类型的操作数完全定义;因此,键类型不能是函数、映射或切片。如果键类型是

我有一张带有复杂键的
地图
——例如,2D数组:

m := make(map[[2][3]int]int)
当我在地图中插入一把新钥匙时,Go是否会对钥匙进行深度复制

a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
m[a] = 1

换句话说,如果我在将数组
a
用作映射键后更改它,映射是否仍然包含
a
的旧值?

数组总是按值传递,因此,在这种情况下,是的Go将生成键的深度副本

比较运算符==和!=必须为键类型的操作数完全定义;因此,键类型不能是函数、映射或切片。如果键类型是接口类型,则必须为动态键值定义这些比较运算符;失败将导致运行时恐慌


这些关键点被复制到地图中。将
map
slice
排除为有效键意味着这些键不能更改。请注意,go不跟随指针如果您将指针定义为键的映射类型(例如
map[*int]int
),它将直接比较指针。

简短回答,它将被复制

根据规范,数组是
值类型

Go的数组是值。数组变量表示整个数组;它不是指向第一个数组元素的指针(在C中就是这样)。这意味着,当分配或传递数组值时,将复制其内容。(为了避免复制,您可以传递指向数组的指针,但那是指向数组的指针,而不是数组。)

你自己看看:

指针不匹配


编辑:真正的原因是插入地图时,会复制键值。或者,您可以继续记住上面的规则:数组是值类型,它们的重用表示一个副本。要么在这里工作。:)

Go中的数组是按值传递的(与切片相反,切片是按引用传递的),因此这与执行
a:=1没有什么区别;m[a]=1
;在执行映射赋值之后,键和变量是不相关的(除了它们可能仍然具有相同的值,除非您更改其中一个)。我在这里对“deep”一词要谨慎一点:在映射中插入一个值会复制键的值,这就是它的全部内容。因为当我们讨论语言原语(赋值运算符,将参数传递给函数)时,Go中的所有内容都是通过值传递/复制的,所以映射键的值就是这样。Go编译器显式分析用作每个映射的键的类型,以捕获使用引用类型的尝试——直接或嵌入到struct type.IOW中,这样的复制不是“深”或“浅”;它是对Go规范定义的值的复制。由于映射键不能使用具有referece语义的类型,复制的结果总是“深”的,但这并不是说它被定义为深而不是浅——它只是Go中传递/复制值的副产品;-)
package main

import (
    "fmt"
)

func main() {
    m := make(map[[2][3]int]int)
    a := [2][3]int{{1, 2, 3}, {4, 5, 6}}

    fmt.Printf("Pointer to a: %p\n", &a)

    m[a] = 1
    for k, _ := range m {
        fmt.Printf("Pointer to k: %p\n", &k)
    }
}