Go: Slice的基础结构与函数

36 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

切片是建立在数组之上的;

数组

数组的定义:指定长度和元素类型;

var a [5]int

数组不需要显式的初始化,已经具备零值

Go的数组是值。数组变量表示整个数组;它不是指向第一个数组元素的指针;也就是说,当分配或传递一个数组的值时,会复制它的内容。

也可以像这样声明数组:

b := [2]string{"hello", "world"}

切片

声明切片与声明数组一样,不过不需要元素个数:[]T,T是元素类型;

c := []int{1,2,3,4}

也可以用make创建切片:

func make([]T, len, cap) []T

该make函数采用类型、长度和容量(可选)。调用时,make分配一个数组并返回引用该数组的切片;省略容量时,容量与长度一样。

s := make([]byte, 5, 5)
// s == []byte{0, 0, 0, 0, 0}
s := make([]byte, 5)

由指向数组的指针、段的长度及其容量组成

image.png

make([]byte,5)

image.png

s = s[2:4]

image.png

切片不会复制数据。而是创建一个指向原始数组的新切片,因此修改新切片的值时会修改原数组的;

切片复制

func copy(dst, src []T) int

从原切片src复制到目标切片dst,返回复制的元素数(以两个参数中较小的元素数量为准);

s := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
fmt.Println(s)
r := make([]byte, 3, 3)
fmt.Println(copy(r, s))
fmt.Println(r)

输出

[103 111 108 97 110 103]
3
[103 111 108]

copy函数可以用来增加切片的容量

s := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
fmt.Printf("len:%d,cap:%d\n", len(s), cap(s))
t := make([]byte, len(s), (cap(s)+1)*2)
copy(t, s)
s = t
fmt.Printf("len:%d,cap:%d\n", len(s), cap(s))

输出

len:6,cap:6
len:6,cap:14

append 追加函数

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

在切片的末尾追加多个元素

a := make([]int, 1)
a = append(a, 1, 2, 3)

在切片末尾追加另一个切片

a := []string{"hello", "world"}
b := []string{"go"}
a = append(a, b...)