为了账号安全,请及时绑定邮箱和手机立即绑定

插入地图时,Go(深)复制键吗?

插入地图时,Go(深)复制键吗?

Go
慕妹3242003 2022-01-17 10:43:47
我有一个map复杂的键 - 例如,二维数组:m := make(map[[2][3]int]int)当我在地图中插入一个新密钥时,Go 是否会对该密钥进行深层复制?a := [2][3]int{{1, 2, 3}, {4, 5, 6}} m[a] = 1换句话说,如果我在将数组a用作映射键后更改数组,映射是否仍包含 的旧值a?
查看完整描述

2 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

简短的回答,它是复制的。


根据规范,数组是value types.


Go 的数组是值。数组变量表示整个数组;它不是指向第一个数组元素的指针(就像 C 中的情况一样)。这意味着当您分配或传递数组值时,您将复制其内容。(为了避免复制,您可以传递一个指向数组的指针,但那是指向数组的指针,而不是数组。) https://blog.golang.org/go-slices-usage-and-internals


你自己看:


https://play.golang.org/p/fEUYWwN-pm


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)

    }

}

指针不匹配。


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


查看完整回答
反对 回复 2022-01-17
?
温温酱

TA贡献1752条经验 获得超4个赞

数组总是按值传递,所以,是的,在这种情况下,Go 会制作密钥的深层副本。

语言规范

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

键被复制到地图中。排除mapslice作为有效密钥意味着密钥不能更改。请注意,如果您使用指针作为键(例如)定义映射类型,则 go 不会跟随指针,map[*int]int它会直接比较指针。


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 148 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信