栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何复制结构和取消引用所有指针

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何复制结构和取消引用所有指针

本质上您想要的是标准库不支持的深层副本。

您的选择:

  • “手动”执行复制,例如,创建新的结构并复制字段,其中必须以递归方式手动复制指针或切片/地图/通道/等。
    通过将您的结构分配给另一个可复制所有字段的结构,这是最容易做到的,因此,您基本上只需要培养指针/地图/切片等(但需要递归)。

  • 使用外部库,例如

    github.com/mohae/deepcopy
    github.com/ulule/deepcopier
    github.com/mitchellh/copystructure

  • 将结构编组为某种格式(例如JSON),然后解组为另一个变量。

最后一个选项可能如下所示:

var i1 Itemdata, err := json.Marshal(i1)if err != nil {    panic(err)}var i2 Itemif err := json.Unmarshal(data, &i2); err != nil {    panic(err)}// i2 holds a deep copy of i1

请注意,封送/取消封送并不是特别有效,而是简单而紧凑的。还要注意,这可能无法很好地处理递归数据结构,甚至可能挂起或出现紧急情况(例如,字段指向包含的结构),但是处理递归结构可能是所有解决方案的问题。另请注意,这不会克隆未导出的字段。

关于封送处理/取消封送处理的好处是,您可以轻松创建一个辅助函数来深度复制“ any”值:

func deepCopy(v interface{}) (interface{}, error) {    data, err := json.Marshal(v)    if err != nil {        return nil, err    }    vptr := reflect.New(reflect.TypeOf(v))    err = json.Unmarshal(data, vptr.Interface())    if err != nil {        return nil, err    }    return vptr.Elem().Interface(), err}

测试它:

p1 := image.Point{X: 1, Y: 2}fmt.Printf("p1 %T %+vn", p1, p1)p2, err := deepCopy(p1)if err != nil {    panic(err)}p1.X = 11fmt.Printf("p1 %T %+vn", p1, p1)fmt.Printf("p2 %T %+vn", p2, p2)

输出(在Go Playground上尝试):

p1 image.Point (1,2)p1 image.Point (11,2)p2 image.Point (1,2)


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/436211.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号