In Go, shallow copy and deep copy are two distinct methods of data replication, and their behavior and impact when handling complex data structures can be significantly different.
Shallow Copy
Shallow copy only copies the top-level elements of the data structure. For reference types within the structure (such as pointers, slices, maps, and interfaces), shallow copy does not copy the underlying data they point to but only copies the references. This means that if elements of reference types in the original data structure are modified, the corresponding data in all shallow copies will also change because they point to the same memory address.
Example:
gotype Person struct { Name string Age int Tags []string } func main() { p1 := Person{Name: "John", Age: 30, Tags: []string{"friendly", "team-player"}} p2 := p1 // Shallow copy p2.Name = "Mike" p2.Tags[0] = "aggressive" fmt.Println(p1) // Output: {John 30 [aggressive team-player]} fmt.Println(p2) // Output: {Mike 30 [aggressive team-player]} }
In this example, although we change the Name field of p2, the Name of p1 remains unchanged; however, when we modify the Tags slice of p2, the corresponding Tags in p1 also change because slices are reference types.
Deep Copy
Deep copy not only copies the top-level elements of the data structure but also recursively copies all underlying data of reference types. This means that during the copy process, a completely independent data copy is created, and any modifications to the original data will not affect the deep copy result.
Example:
gofunc 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) // Output: {John 30 [friendly team-player]} fmt.Println(p2) // Output: {Mike 30 [aggressive team-player]} }
In this example, JSON serialization and deserialization are used to achieve deep copy. As seen, modifications to p2 do not affect p1 at all because they are completely independent copies.
Summary
Whether to choose shallow copy or deep copy depends on your specific requirements. If you need completely independent data copies, use deep copy. If you only need to copy the top-level data of the structure and understand the implications of data sharing, you can use shallow copy.