复制一个结构体。

huangapple go评论97阅读模式
英文:

Make a copy of a struct

问题

我正在尝试在Go语言中制作一个结构体的深拷贝。在自己构建解决方案之前,我试图找到Go语言中惯用的方法来实现深拷贝。我找到了对于这个问题的这个实现的参考。然而,它似乎已经过时并且没有得到积极维护。我相信这是一个人们经常需要的场景,所以我一定是遗漏了什么。有人能给予任何指导吗?

英文:

I am attempting to make a deep copy of a struct in go. Before going and building a solution myself, I attempted to find the idiomatic way to do so in go. I did find reference to this implementation. However, it appears to be well out of date and not actively maintained. I'm sure this is a scenario that people much require from time-to-time so I must be missing something. Does anybody have any guidance?

答案1

得分: 1

更近期的Google deepcopy代码版本可以在margnus1/go-deepcopy中找到。

这段代码说明了为什么标准库中没有深拷贝。

// 基本的拷贝算法:
// 1) 递归扫描对象,构建一个指向对象的所有分配内存范围的列表。
// 2) 递归拷贝对象,确保数据结构内的引用指向新分配的数据结构中的适当位置。

整个算法相当复杂,并且依赖于反射。当然,只能访问导出字段。

// Copy对obj进行递归深拷贝,并返回结果。
//
// 在obj中,指针之间的相等性保持不变,
// 指向相同底层数据的切片之间的关系也保持不变,
// 尽管数据本身将被拷贝。
// a := Copy(b) 意味着 reflect.DeepEqual(a, b)。
// Map的键不会被拷贝,因为reflect.DeepEqual不会递归进入map的键。
// 由于reflect包的限制,只有所有成员都是公开的类型才能被拷贝。
//
func Copy(obj interface{}) (r interface{}) {

> 我确定这是人们时不时需要的一种情况,所以我一定是漏掉了什么

正如这个帖子中提到的

> 与传递结构体指针相比,传递结构体值通常已经足够了。如果程序员足够善于有效地设计树或图结构,那么他们可能能够预见到共享这样的结构可能会出现的问题。
我们中的许多人认为,强制性的深拷贝行为的缺失是一种特性,因为我们希望Go提供的工具能够帮助确保安全性,而不是阻碍效率。


更近期和更完善的深拷贝版本是ulule/deepcopier

// 将instance1深拷贝到instance2
Copy(instance1).To(instance2)
英文:

A more recent version of the google deepcopy code can be found in margnus1/go-deepcopy.

It does illustrate why there is no deepcopy in the standard library.

// basic copy algorithm:
// 1) recursively scan object, building up a list of all allocated
// memory ranges pointed to by the object.
// 2) recursively copy object, making sure that references
// within the data structure point to the appropriate
// places in the newly allocated data structure.

The all algo is quite convoluted and rely on reflection. And of course only access exported field.

// Copy makes a recursive deep copy of obj and returns the result.
//
// Pointer equality between items within obj is preserved,
// as are the relationships between slices that point to the same underlying data,
// although the data itself will be copied.
// a := Copy(b) implies reflect.DeepEqual(a, b).
// Map keys are not copied, as reflect.DeepEqual does not
// recurse into map keys.
// Due to restrictions in the reflect package, only
// types with all public members may be copied.
//
func Copy(obj interface{}) (r interface{}) {

> I'm sure this is a scenario that people much require from time-to-time so I must be missing something

As mentioned in this thread:

> Passing struct values as opposed to struct pointers, for example, is generally good enough. If the programmer is good enough to effectively design tree or graph structures, then they can probably anticipate problems with sharing such a structure.
Many of us consider the absence of mandatory deep-copy behavior to a feature, since we want Go to provide tools to aid safety, not obstacles to efficiency.


A more recent and polished version of deepcopy is ulule/deepcopier

// Deep copy instance1 into instance2
Copy(instance1).To(instance2)

huangapple
  • 本文由 发表于 2015年7月25日 23:30:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/31628099.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定