Go基础Slice教程详解

2019-11-10 11:34:28于海丽

Go 语言切片(Slice)

Go 语言切片是对数组的抽象。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

声明Slice

带有 T 类型元素的切片由 []T 表示,其中T代表slice中元素的类型。切片在内部可由一个结构体类型表示,形式如下:

type slice struct { 
 Length  int
 Capacity  int
 ZerothElement *byte
}

可见一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。通过len和cap函数分别返回slice的长度和容量。

创建Slice

直接声明创建 slice

[]<元素类型>{元素1, 元素2, …}

创建一个有 3 个整型元素的数组,并返回一个存储在 c 中的切片引用。

c := []int{6, 7, 8}

make() 函数创建 slice

s1 := make([]int, 5) //长度和容量都是 5
 s2 := make([]int, 3, 10) //长度是3,容量是10
 fmt.Println(cap(s1),s2)

基于底层数组数组或切片创建

基于现有的切片或者数组创建,使用[i:j]这样的操作符即可,她表示以i索引开始,到j索引结束,截取原数组或者切片,创建而成的新切片,新切片的值包含原切片的i索引,但是不包含j索引。注意i和j都不能超过原切片或者数组的索引

slice :=[]int{1,2,3,4,5}
 slice1 := slice[:]
 slice2 := slice[0:]
 slice3 := slice[:5]
 fmt.Println(slice1)
 fmt.Println(slice2)
 fmt.Println(slice3)

新的切片和原数组或原切片共用的是一个底层数组,所以当修改的时候,底层数组的值就会被改变,所以原切片的值也改变了。

slice := []int{1, 2, 3, 4, 5}
 newSlice := slice[1:3]
 newSlice[0] = 10
 fmt.Println(slice)
 fmt.Println(newSlice)

切片与数组的区别

1.切片不是数组,但是切片底层指向数组

2.切片本身长度是不一定的因此不可以比较,数组是可以的。

3.切片是变长数组的替代方案,可以关联到指向的底层数组的局部或者全部。

4.切片是引用传递(传递指针地址),而数组是值传递(拷贝值)

5.切片可以直接创建,引用其他切片或数组创建

6.如果多个切片指向相同的底层数组,其中一个值的修改会影响所有的切片

切片的修改

切片自己不拥有任何数据。它只是底层数组的一种表示。对切片所做的任何修改都会反映在底层数组中。