乐闻世界logo
搜索文章和话题

Go中浅拷贝和深拷贝有什么区别?

4 个月前提问
3 个月前修改
浏览次数7

1个答案

1

在Go语言中,浅拷贝和深拷贝是两种不同的数据复制方式,它们在处理复杂数据结构时的表现和影响也有很大的不同。

浅拷贝(Shallow Copy)

浅拷贝仅仅复制数据结构的顶层元素,对于其中的引用类型(如指针、切片、映射、接口等),浅拷贝不会复制它们所指向的底层数据,而是仅仅复制引用。这意味着,如果原始数据结构中的引用类型的元素被修改,那么所有的浅拷贝副本中相应的数据也会发生变化,因为它们指向的是同一块内存地址。

例子:

go
type Person struct { Name string Age int Tags []string } func main() { p1 := Person{Name: "John", Age: 30, Tags: []string{"friendly", "team-player"}} p2 := p1 // 浅拷贝 p2.Name = "Mike" p2.Tags[0] = "aggressive" fmt.Println(p1) // 输出: {John 30 [aggressive team-player]} fmt.Println(p2) // 输出: {Mike 30 [aggressive team-player]} }

在这个例子中,尽管我们改变了p2Name字段,p1Name并没有变化;但是当我们修改p2Tags切片时,p1中相应的Tags也发生了变化,因为切片是引用类型。

深拷贝(Deep Copy)

深拷贝不仅复制数据结构的顶层元素,还会递归地复制所有引用类型的底层数据。这意味着,复制过程中会创建一份完全独立的数据副本,原始数据的任何修改都不会影响到深拷贝的结果。

例子:

go
func DeepCopy(src, dst interface{}) { marshall, _ := json.Marshal(src) json.Unmarshal(marshall, dst) } func main() { p1 := Person{Name: "John", Age: 30, Tags: []string{"friendly", "team-player"}} var p2 Person DeepCopy(p1, &p2) p2.Name = "Mike" p2.Tags[0] = "aggressive" fmt.Println(p1) // 输出: {John 30 [friendly team-player]} fmt.Println(p2) // 输出: {Mike 30 [aggressive team-player]} }

在这个例子中,使用了JSON序列化和反序列化来实现深拷贝。可以看到,p2的修改完全不影响p1,因为它们是完全独立的两份数据。

总结

选择浅拷贝还是深拷贝,取决于你的具体需求。如果你需要完全独立的数据副本,应该使用深拷贝。如果你只需要复制数据结构的表层数据,并且对数据共享的影响有所了解,则可以使用浅拷贝。

2024年8月9日 03:01 回复

你的答案