也许这是一个非常菜鸟的问题,但我不能完全理解为什么这种差异会发生在我的复制方法。
到目前为止,我一直假设你不能复制Map,因为内部结构是一个“引用”,所有你传递的基本上是一个Map头。
给出以下简化示例:
// go version go1.19.6 linux/amd64
var globalMap = map[int]string{
0: "foo",
1: "bar",
}
func copyGlobalMap() map[int]string {
copiedMap := make(map[int]string)
globalMap, copiedMap = copiedMap, globalMap
return copiedMap
}
func copyMap(sourceMap map[int]string) map[int]string {
copiedMap := make(map[int]string)
sourceMap, copiedMap = copiedMap, sourceMap
return copiedMap
}
func main() {
fmt.Println("--- Example 1 ----")
copiedMap := copyMap(globalMap)
globalMap[1] = "moo"
fmt.Printf("Original map %+v\n", globalMap)
fmt.Printf("Copied map %+v\n", copiedMap)
fmt.Println("--- Example 2 ----")
copiedMap = copyGlobalMap()
globalMap[1] = "moo"
fmt.Printf("Original map %+v\n", globalMap)
fmt.Printf("Copied map %+v\n", copiedMap)
}
我收到以下输出:
--- Example 1 ----
Original map map[0:foo 1:moo]
Copied map map[0:foo 1:moo]
--- Example 2 ----
Original map map[1:moo]
Copied map map[0:foo 1:moo]
正如你所看到的,例1的行为和通常一样,思维导图是“* 纠缠 *”的。但是第二个例子似乎暗示了一个单独的副本被实现了。
有谁能解释一下为什么这(看起来?)有效?
注意:在一个代码库中观察到这样的全局交换,对全局缓存进行了快照。首先,我不相信它工作正常,但似乎是。
1条答案
按热度按时间abithluo1#
这个函数不复制任何东西。
copiedMap := make(map[int]string)
sourceMap, copiedMap = copiedMap, sourceMap
copiedMap
现在定位***原始***sourceMap
;sourceMap
现在定位您创建的新的空Map。return copiedMap
copiedMap
的当前值返回给调用者。这将是原始的sourceMap
如果您这样做:
你会发现
src
和cpy
现在都有4个元素。如果你真的想创建一个Map的副本,它只是: