在 Go 中,深拷贝和浅拷贝都是针对复合类型(比如结构体、切片、映射等)的。简单类型(如 int、float 等)是没有深拷贝和浅拷贝之分的。

浅拷贝

浅拷贝是指复合类型的值只拷贝了其指针,而没有拷贝指针指向的底层数据。也就是说,拷贝前后两个变量指向的是同一块内存地址,它们共享底层数据。这意味着,如果修改了其中任意一个变量的值,另外一个变量的值也会受到影响。

在 Go 中,使用赋值语句进行的拷贝都是浅拷贝。比如:

// 浅拷贝
a := []int{1, 2, 3}
b := a
b[0] = 4
fmt.Println(a) // [4 2 3]
fmt.Println(b) // [4 2 3]

深拷贝

深拷贝则是在拷贝时,不仅拷贝了指针,还拷贝了指针指向的底层数据。也就是说,拷贝前后的两个变量指向的是不同的内存地址,它们各自拥有一份独立的底层数据。这样,修改其中任意一个变量的值,另外一个变量的值不会受到影响。

在 Go 中,由于深拷贝需要对复合类型的底层数据进行递归拷贝,所以相对来说会比较耗费资源。通常情况下,我们可以通过自定义深拷贝函数来实现深拷贝。比如:

// 自定义深拷贝函数
func deepCopy(src []int) []int {
    dst := make([]int, len(src))
    for i, v := range src {
        dst[i] = v
    }
    return dst
}

// 深拷贝
a := []int{1, 2, 3}
b := deepCopy(a)
b[0] = 4
fmt.Println(a) // [1 2 3]
fmt.Println(b) // [4 2 3]

需要注意的是,自定义深拷贝函数需要对复合类型的每一个字段都进行递归拷贝,否则可能会出现浅拷贝的问题。同时,对于嵌套的复合类型(比如结构体中嵌套切片),也需要进行递归拷贝。

Go 语言深拷贝和浅拷贝详解:概念、区别和实现

原文地址: https://www.cveoy.top/t/topic/lAAm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录