一次帮同事 review 代码,想在 go 里面找一个支持深度 Copy 的库,github 上少得可怜。最后找到 json marshal 加 unmarshal 的方式,但是这种方式有两个缺点,第 1 marshal 一次 reflect,unmarshal 一次 reflect,有两次 reflect 的过程,效率会垫底。第 2,不支持过滤条件,这点硬伤,改不了。特对这两点问题,所以想撸个改进版本(更快,更可控)。
https://github.com/antlabs/deepcopy
deepcopy.Copy 主要用于两个类型间的深度拷贝[从零实现]
go get github.com/antlabs/deepcopy
package main
import (
"fmt"
"github.com/antlabs/deepcopy"
)
type dst struct {
ID int
Result string
}
type src struct{
ID int
Text string
}
func main() {
d, s := dst{}, src{ID:3}
deepcopy.Copy(&d, &s).Do()
fmt.Printf("%#v\n", d)
}
如果 src 的结构体嵌套了两套,MaxDepth 可以控制只拷贝一层
deepcopy.Copy(&dst{}, &src{}).MaxDepth(1).Do()
只拷贝结构体里面有 copy tag 的字段,比如下面只会拷贝 ID 成员
package main
import (
"fmt"
"github.com/antlabs/deepcopy"
)
type dst struct {
ID int `copy:"ID"`
Result string
}
type src struct {
ID int `copy:"ID"`
Result string
}
func main() {
d := dst{}
s := src{ID: 3, Result: "use tag"}
deepcopy.Copy(&d, &s).RegisterTagName("copy").Do()
fmt.Printf("%#v\n", d)
}
package main
import (
"fmt"
"github.com/antlabs/deepcopy"
)
func main() {
i := []int{1, 2, 3, 4, 5, 6}
var o []int
deepcopy.Copy(&o, &i).Do()
fmt.Printf("%#v\n", o)
}
package main
import (
"fmt"
"github.com/antlabs/deepcopy"
)
func main() {
i := map[string]int{
"cat": 100,
"head": 10,
"tr": 3,
"tail": 44,
}
var o map[string]int
deepcopy.Copy(&o, &i).Do()
fmt.Printf("%#v\n", o)
}
从零实现的 deepcopy 相比 json 序列化与反序列化方式拥有更好的性能
goos: linux
goarch: amd64
pkg: github.com/antlabs/deepcopy
Benchmark_MiniCopy-12 243212 4987 ns/op
Benchmark_DeepCopy-12 273775 4781 ns/op
PASS
ok github.com/antlabs/deepcopy 4.496s
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.