【问题标题】:How do you perform a deep copy of a struct in Go?你如何在 Go 中执行结构的深拷贝?
【发布时间】:2014-10-27 23:24:38
【问题描述】:

我正在尝试执行以下结构的深层复制:

// Ternary Tree
type Tree struct {
    Left  *Tree
    Mid *Tree
    Right *Tree
    Value interface{}
    Parent *Tree
    Orientation string
    IsTerminal bool
    Type string
}

以下是我很抱歉的尝试。看起来我正在根处创建一棵新树,但它的孩子仍然指向内存中的相同地址。

func (tree *Tree) CopyTree() *Tree {
    if (tree == nil) {
        return nil
    } else {
        copiedTree := &Tree {
            tree.Left.CopyTree(),
            tree.Mid.CopyTree(),
            tree.Right.CopyTree(),
            tree.Value,
            tree.Parent.CopyTree(),
            tree.Orientation,
            tree.IsTerminal,
            tree.Type}
        return copiedTree
    }
}

在 Go 中是否有任何有用的结构可以帮助深度复制结构?如果没有,我将如何自己执行此深层复制?请注意,“deepcopy”包不再有效,因为它使用了一些在 Go 1 中被弃用的函数

【问题讨论】:

  • 没有内置任何东西。但是有packages such as DeepCopy that can do it for you(请记住“实验”状态)
  • @SimonWhitehead 我试了一下那个包。不幸的是,它使用了一堆随着 Go 1 的发布而被弃用的函数
  • 道歉..我没有意识到(我必须在 Go 1 之前使用它)。
  • 您确定您提供的代码演示了您描述的行为吗?似乎有一个无限循环,父复制子复制父。另外,您不是在复制价值:这是有意的吗?
  • @Anonymous 我不确定!而且,不,这不是故意的。

标签: go deep-copy


【解决方案1】:

我很接近。我应该已将copyedTree 分配给父属性。

func (tree *Tree) CopyTree() *Tree {
    if (tree == nil) {
        return nil
    } else {
        copiedTree := &Tree {
            tree.Left.CopyTree(),
            tree.Mid.CopyTree(),
            tree.Right.CopyTree(),
            tree.Value,
            nil,
            tree.Orientation,
            tree.IsTerminal,
            tree.Type,
        }

        if copiedTree.Left != nil {
            copiedTree.Left.Parent = copiedTree
        }
        if copiedTree.Right != nil {
            copiedTree.Right.Parent = copiedTree
        }
        if copiedTree.Mid != nil {
            copiedTree.Mid.Parent = copiedTree
        }
        return copiedTree
    }
}

【讨论】:

    【解决方案2】:

    json.Marshal 和 json.Unmarshal 怎么样。如果性能很关键,我更喜欢使用 protobuf。

    【讨论】:

      【解决方案3】:

      你可以通过encoding/gob来回:

      package main
      
      import (
         "bytes"
         "encoding/gob"
      )
      
      func copyStruct(in, out interface{}) {
         buf := new(bytes.Buffer)
         gob.NewEncoder(buf).Encode(in)
         gob.NewDecoder(buf).Decode(out)
      }
      
      func main() {
         type date struct { Month, Day int }
         a := date{12, 31}
         var b date
         copyStruct(a, &b)
      }
      

      https://golang.org/pkg/encoding/gob

      【讨论】:

        猜你喜欢
        • 2022-01-15
        • 2011-08-31
        • 1970-01-01
        • 1970-01-01
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        相关资源
        最近更新 更多