切片创建方法

1. 数组切片创建

1
2
3
4
5
6
7
8
func main() {
array := []int{0, 1, 2, 3, 4, 5}
slice := array[2: 4]
fmt.Println(array)
fmt.Println(slice)
// array -> [0, 1, 2, 3, 4, 5]
// slice -> [2, 3]
}

这里需要注意一下,go的切片与python不一样,[start: end]返回的是下标 array[start]array[end-1]的元素.

不填start默认为0

不填end默认为数组长度+1

2. make内置函数创建

1
2
3
4
5
6
7
8
9
func main() {
slice := make([]int, 4, 10)
fmt,Println(slice)
// [0 0 0 0]
slice[0] = 10
slice[1] = 20
fmt.Println(slice)
// [10 20 0 0]
}

make创建切片的参数:

  1. type -> 切片类型
  2. size -> 切片长度
  3. Interger -> 切片容量

切片的坑点

什么情况下会是引用,什么情况下是拷贝

在我们使用内置函数append时,若切片长度小于容量则不会创建新的切片,若切片长度大于等于容量,则go会创建新的切片并拷贝原切片到新的切片上同时扩大容量。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
slice1 := make([]int, 4, 5)
slice2 := append(slice1, 50)
fmt.Println(slice1)
fmt.Println(slice2)
// [0 0 0 0]
// [0 0 0 0 50]
slice2[0] = 10
slice2[1] = 20
fmt.Println(slice1)
fmt.Println(slice2)
// [10 20 0 0]
// [10 20 0 0 50]
}

我们可以发现,在容量充足情况下,append后是引用原切片的,我们对新切片内的值进行修改,原切片也会被改变。

这绝对是一个大坑点,我们若是在项目中不注意很可能修改一处数据导致多处数据被修改

那么有没有避免的方法呢?

有!

我们创建新切片的时候让长度与容量一样这样在追加操作的时候就会生成新的底层数组,从而与原有数组分离。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
slice1 := make([]int, 4, 4)
slice2 := append(slice1, 50)
fmt.Println(slice1)
fmt.Println(slice2)
// [0 0 0 0]
// [0 0 0 0 50]
slice2[0] = 10
slice2[1] = 20
fmt.Println(slice1)
fmt.Println(slice2)
// [0 0 0 0]
// [10 20 0 0 50]
}