Fork me on GitHub

Go中切片之间的浅拷贝和深拷贝

我们知道,go语言中切片类型是从数组类型基础上发展出来的新类型,当声明一个数组时,不指定该数组长度,则该类型为切片(“动态数组”),切片有自己独立的内部结构字段(len, cap, array pointer),并共用底层数组空间。

例如:

1
2
var s1 [10]int //数组
var s2 []int //切片

切片属于引用类型,使用make分配内存空间和初始化成员结构。

1
2
a := make([]int, 3)  		//长度为3
b := make([]int, 3, 5) //长度为3,容量为5

切片字面量初始化:

数组到切片的拷贝(共享底层数组空间)

切片之间的拷贝分为2种:浅拷贝和深拷贝

浅拷贝:

源切片和目的切片共享同一底层数组空间,源切片修改,目的切片同样被修改。

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main(){
slice1 := make([]int, 5, 5)
slice2 := slice1
slice1[1] = 1
fmt.Println(slice1) //[0 1 0 0 0]
fmt.Println(slice2) //[0 1 0 0 0]
}
深拷贝:

源切片和目的切片各自都有彼此独立的底层数组空间,各自的修改,彼此不受影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main(){
slice1 := make([]int, 5, 5)
slice1[0]=9
slice2 := make([]int, 4, 4)
slice3 := make([]int, 5, 5)
//拷贝
fmt.Println(copy(slice2, slice1))//4
fmt.Println(copy(slice3, slice1))//5
//独立修改
slice2[1] = 2
slice3[1] = 3
fmt.Println(slice1)//[9 0 0 0 0 0]
fmt.Println(slice2)//[9 2 0 0]
fmt.Println(slice3)//[9 3 0 0 0]
}
您的鼓励是我持之以恒的动力