Go语言中的深拷贝与浅拷贝解析

发表时间: 2024-05-01 09:47

深拷贝和浅拷贝

切片是引用(传递)类型

package mainimport "fmt"func main() {//1.数组:值类型    a1 := [4]int{1, 2, 3, 4, 5, 6}    a2 := a1 //值传递:传递的是数据    fmt.Println(a1, a2)    a1[0] = 100    fmt.Println(a1, a2)    //2.切片:引用类型    s1 := []int{1, 2, 3, 4}    s2 := s1    fmt.Println(s1, s2)    s1[0] = 100    fmt.Println(s1, s2)    fmt.Printf("%p\n", s1)    fmt.Printf("%p\n", s2)    fmt.Printf("%p\n", &s1)    fmt.Printf("%p\n", &s1)}/*[1 2 3 4 5 6] [1 2 3 4 5 6][100 2 3 4 5 6] [1 2 3 4 5 6][1 2 3 4 5 6] [1 2 3 4 5 6][100 2 3 4 5 6] [100 2 3 4 5 6]0xc00000e2800xc00000e2800xc0000040780xc000004078*/


按照数据类型来分:

基本数据类型:int,float,string,bool

复合数据类型: array,slice,map,struct,pointer,finction,chan


按照传递特点来分:

值类型:int,float,string,bool,array

传递的是数据副本

引用类型:slice

传递的地址,多个变量指向了同一块内存地址。

所以:切片是引用类型的数据,存储了底层数组的引用



深拷贝和浅拷贝的区别

package mainimport "fmt"/*func copy(dst,src[]Type)int可以实现切片的拷贝*/func main() {    s1 := []int{1, 2, 3, 4, 5, 6}    s2 := make([]int, 0) //len:0,cap:0    for i := 0; i < len(s1); i++ {    s2 = append(s2, s1[i])    }    fmt.Println(s1)    fmt.Println(s2)    s1[0] = 100    fmt.Println(s1)    fmt.Println(s2)    //copy()    s3 := []int{7, 8, 9, 10}    fmt.Println(s2)    fmt.Println(s3)    //copy(s2,s3)//将s3中的元素,拷贝到s2中    //copy(s3,s2)//将s2中的元素,拷贝到s3中    copy(s3[1:], s2[2:])    fmt.Println(s2)    fmt.Println(s3)}/*[1 2 3 4 5 6][1 2 3 4 5 6][100 2 3 4 5 6][1 2 3 4 5 6][1 2 3 4 5 6][7 8 9 10][1 2 3 4 5 6][7 3 4 5 6]*/

深拷贝: 拷贝的是数据底层本身。

值类型的数据,默认都是深拷贝:array,int,float,string,bool,struct


浅拷贝:拷贝的是数据(内存)地址。

导致多个变量指向同一块内存地址

引用类型的数据,默认都是浅拷贝:slice,map

因为切片是引用类型的数据,直接拷贝的是地址。


注意: 深拷贝和浅拷贝概念等同于值传递和引用传递;