问题 是否有内置功能去制作任意地图的副本?


是否有内置功能去制作任意地图的副本?

我可以手工编写,但我之前发现当我想对地图进行深入比较时,我正在寻找类似的问题,似乎已经内置了一个函数!所以类似地,也许我想知道是否有内置的或一些库或包用于在golang中制作地图的深层副本。我相信我不是第一个想要复制地图的人。

副本我的意思是你可以创建两个不同的变量来引用内存中的不同映射,即使它们是相同的内容。


8210
2018-04-12 16:33


起源

可能重复 Go:将地图的所有元素复制到另一个元素中 - Rick Smith


答案:


有关更一般的答案,您可以对地图进行编码并使用新变量对其进行解码 编码/料滴

这种方式的优点是它甚至可以处理更复杂的数据结构,比如包含一片地图的结构片。

package main

import (
    "bytes"
    "encoding/gob"
    "fmt"
    "log"
)

func main() {
    ori := map[string]int{
        "key":  3,
        "clef": 5,
    }

    var mod bytes.Buffer
    enc := gob.NewEncoder(&mod)
    dec := gob.NewDecoder(&mod)

    fmt.Println("ori:", ori) // key:3 clef:5
    err := enc.Encode(ori)
    if err != nil {
        log.Fatal("encode error:", err)
    }

    var cpy map[string]int
    err = dec.Decode(&cpy)
    if err != nil {
        log.Fatal("decode error:", err)
    }

    fmt.Println("cpy:", cpy) // key:3 clef:5
    cpy["key"] = 2
    fmt.Println("cpy:", cpy) // key:2 clef:5
    fmt.Println("ori:", ori) // key:3 clef:5
}

如果你想了解更多关于gobs的信息,可以选择 关于它的博客文章。


8
2018-02-18 08:45



这种方法比使用反射包的等效方法更快还是更慢? - Aaron
今天我花了一点时间来实现这个深度复制map [string] interface {}类型,特别是测试。这是代码,以防为其他人节省时间: gist.github.com/soroushjp/0ec92102641ddfc3ad5515ca76405f4d  该实现应适用于任何其他Go类型与小调整。还建议看看这个答案: stackoverflow.com/questions/21934730/... - soroushjp


不,没有 内建的 地图深拷贝的单行。

但是,有一个 迭代解决方案 以及ASA 深层复制的通用包


3
2018-04-12 17:01



深层复制的通用包是否适用于地图? - Pinocchio
@Pinocchio:AFAIK,是的。 - bishop
你如何使用它?我尝试导入“code.google.com/p/rog-go/exp/deepcopy”并说:prog.go:5:找不到导入:“code.google.com/p/rog-go/ exp / deepcopy“[进程以非零状态退出] - Pinocchio
看起来代码是详细的,并且不会在Go 1下编译 - Tomas
@Pinocchio:我现在不在我的终端附近,所以我不能像我想的那样进行测试,但你试过了吗? 得到所有? - bishop


为了增加Simpfally的答案,有些人会想到 encoding/gob 是结构,只复制导出的字段。并且频道无法编码。


1
2018-03-16 06:02





复制地图是一些简单的代码行。只需编写代码,尽情享受每个简单代码必须在库中的想法!

original := map[string]int{
    "Hello": 4,
    "World": 123,
}

copy := map[string]int{}
for k, v := range original {
    copy[k] = v
}

0
2018-04-13 06:33



虽然我一般同意你的看法,但是内置的克隆映射可能对大型地图具有性能优势:迭代插入被迫通过散列密钥,将其分类到存储桶中,将其与该存储桶中的值进行比较 - 这就是地图中的每一对。相反,内置可以克隆所有内部结构,无需重新计算任何内容。 - kostix
鉴于存在 len 和 append, copy 出于性能原因,似乎是一个明显的补充。 - Rick-777
这是一个浅拷贝,深拷贝是一堆更复杂的,特别是如果地图包含自己(或父亲甚至) - David Budworth
这个答案说明了为什么内置对性能有帮助的原因。正确的副本不是 不重要的 由于作者忘记给出分配的大小提示: copy := make(map[string]int{}, len(original)) - dolmen