GO 中的深拷贝和浅拷贝

数组的深浅拷贝

  1. 浅拷贝(Shallow Copy): 浅拷贝只是复制了数据结构的引用,而不是复制数据结构本身。这意味着新的数据结构和原始数据结构共享相同的底层数据。如果修改了其中一个数据结构,另一个数据结构也会受到影响。浅拷贝通常是通过直接赋值或者切片操作来实现的。
1
2
3
go复制代码// 浅拷贝示例
slice1 := []int{1, 2, 3}
slice2 := slice1 // 浅拷贝

在上面的示例中,slice2slice1 的浅拷贝,它们共享相同的底层数组。
2. 深拷贝(Deep Copy): 深拷贝会复制整个数据结构,包括其所有的子数据结构,从而创建一个完全独立的副本。这意味着新的数据结构和原始数据结构是完全独立的,彼此不受影响。深拷贝通常需要递归地复制数据结构的所有子结构。

1
2
3
4
go复制代码// 深拷贝示例
slice1 := []int{1, 2, 3}
slice2 := make([]int, len(slice1))
copy(slice2, slice1) // 深拷贝

在上面的示例中,通过使用 copy 函数将 slice1 的内容复制到了一个新的切片 slice2 中,这样就实现了深拷贝。

结构体的深拷贝

在 Go 中,结构体的深拷贝通常需要手动编写代码来实现,因为结构体的复制通常只是浅拷贝。深拷贝需要递归地复制结构体的所有字段,包括其中包含的其他结构体字段。

以下是一个示例,演示了如何对结构体进行深拷贝:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
go复制代码package main

import (
"fmt"
"reflect"
)

// 定义一个结构体
type Person struct {
Name string
Age int
Address Address
}

type Address struct {
City string
State string
}

// 实现一个深拷贝函数
func DeepCopy(src interface{}) interface{} {
srcValue := reflect.ValueOf(src)

// 获取原始结构体类型
srcType := reflect.TypeOf(src)

// 创建一个与原始结构体类型相同的新结构体变量
dst := reflect.New(srcType).Elem()

// 遍历原始结构体的字段
for i := 0; i < srcValue.NumField(); i++ {
field := srcValue.Field(i)

// 如果字段是结构体类型,则递归进行深拷贝
if field.Kind() == reflect.Struct {
fieldValue := DeepCopy(field.Interface())
dst.Field(i).Set(reflect.ValueOf(fieldValue))
} else {
// 如果字段是基本类型,则直接复制值
dst.Field(i).Set(field)
}
}

return dst.Interface()
}

func main() {
// 创建一个原始结构体
person1 := Person{
Name: "Alice",
Age: 30,
Address: Address{
City: "New York",
State: "NY",
},
}

// 对原始结构体进行深拷贝
person2 := DeepCopy(person1).(Person)

// 修改深拷贝后的结构体
person2.Name = "Bob"
person2.Age = 40
person2.Address.City = "Los Angeles"

// 打印原始结构体和深拷贝后的结构体
fmt.Println("Original struct:", person1)
fmt.Println("Deep copied struct:", person2)
}

在上面的示例中,我们定义了一个 Person 结构体和一个 Address 结构体。然后,我们实现了一个名为 DeepCopy 的函数,用于对结构体进行深拷贝。该函数使用了反射来处理结构体的字段,对字段进行递归的深拷贝。最后,我们创建了一个原始结构体 person1,并通过 DeepCopy 函数对其进行了深拷贝,得到了 person2。通过打印结果,我们可以看到原始结构体和深拷贝后的结构体是独立的,彼此不受影响。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%