Skip to content

Slice 切片

切片和数组

切片其实就是 Go 提供的动态数组。

切片和普通数组在创建的语法上,最大的区别就是,切片不指定长度。

go
package main

import "fmt"

func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}	// 数组

	var s []int = primes[1:4]	// 切片,这里的切片元素直接从数组里面取了 3 5 7
	fmt.Println(s)
}

切片通过两个下标来界定,一个下界和一个上界,二者以冒号分隔:

a[low : high]

它会选出一个半闭半开区间,包括第一个元素,但排除最后一个元素。

切片的长度与容量

切片是由底层的数组抽象而来。

切片的容量 = 切片首个元素对应的底层数组元素到底层数组末尾元素的个数 ≥ 切片的长度。

切片长度是人为定义的范围,超出范围即便是在容量内也不能使用,需要使用 append 函数增加长度后才可以访问。

使用make创建切片

切片的创建最常见的是使用make函数。

make 的第二个参数可直接指定长度:函数会为所有元素分配零值。

a := make([]int, 5)  // len(a)=5

要指定它的容量,需向 make 传入第三个参数:

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:]      // len(b)=4, cap(b)=4

向切片追加元素

Go 提供了内置的 append 函数。

func append(s []T, vs ...T) []T

append 的第一个参数是一个现有的元素类型为 T 的切片,后面的参数是新的元素,新的元素会追加到该切片的末尾。

append 的结果是一个包含原切片所有元素加上新添加元素的切片。

go
func main() {
	var s []int
	printSlice(s)

	// 可在空切片上追加
	s = append(s, 0)
	printSlice(s)

	// 这个切片会按需增长
	s = append(s, 1)
	printSlice(s)

	// 可以一次性添加多个元素
	s = append(s, 2, 3, 4)
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

若执行 append 时,切片容量不够追加元素(长度增加),运行时会重新分配内存以处理这个操作(就是把现在的底层数组数据拷贝到一个新的、更大的底层数组上去)。