likes
comments
collection
share

GO 中的深拷贝和浅拷贝

作者站长头像
站长
· 阅读数 46

数组的深浅拷贝

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

    // 浅拷贝示例
    slice1 := []int{1, 2, 3}
    slice2 := slice1 // 浅拷贝
    

    在上面的示例中,slice2slice1 的浅拷贝,它们共享相同的底层数组。

  2. 深拷贝(Deep Copy): 深拷贝会复制整个数据结构,包括其所有的子数据结构,从而创建一个完全独立的副本。这意味着新的数据结构和原始数据结构是完全独立的,彼此不受影响。深拷贝通常需要递归地复制数据结构的所有子结构。

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

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

结构体的深拷贝

在 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。通过打印结果,我们可以看到原始结构体和深拷贝后的结构体是独立的,彼此不受影响。

转载自:https://juejin.cn/post/7359893253170774052
评论
请登录