繁体   English   中英

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

[英]How to copy struct and dereference all pointers

如何将Item结构和所有指针复制到新结构?

type Item struct {
    A    []*ASet     `json:"a,omitempty"`
    B    []*BSet.    `json:"b,omitempty"`
    C    []*CSet.    `json:"c,omitempty"`
}


type ASet struct {
    UID   string     `json:"uid,omitempty"`
    Items []*ItemA `json:"member,omitempty"`
}

type ItemA struct {
    UID  string `json:"uid,omitempty"`
    Portset []*PortSet `json:"portset,omitempty"`
}

type PortSet struct {
    UID   string     `json:"uid,omitempty"`
    Ports []*Port `json:"member,omitempty"`
}

type Port struct {
    UID  string `json:"uid,omitempty"`
    Port int    `json:"port,omitempty"`
}

我不希望新结构引用旧结构。

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

您的选择:

  • “手动”执行复制,例如,创建新的结构并复制字段,其中必须以递归的方式手动复制指针或切片/地图/通道/等。
    通过将您的结构分配给另一个可复制所有字段的结构,这是最容易做到的,因此,您基本上只需要培养指针/地图/切片等(但需要递归)。
  • 使用外部库,如github.com/mohae/deepcopygithub.com/ulule/deepcopiergithub.com/mitchellh/copystructure
  • 将您的结构编组为某种格式(例如JSON),然后解组为另一个变量。

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

var i1 Item
data, err := json.Marshal(i1)
if err != nil {
    panic(err)
}

var i2 Item
if 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 %+v\n", p1, p1)

p2, err := deepCopy(p1)
if err != nil {
    panic(err)
}

p1.X = 11
fmt.Printf("p1 %T %+v\n", p1, p1)
fmt.Printf("p2 %T %+v\n", p2, p2)

输出(在Go Playground上尝试):

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM