Abner的博客

Go基础-切片

· 99 words · 1 minutes to read
Categories: Go

内部实现 🔗

切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象 切片对象非常小,是因为它是只有3个字段的数据结构:一个是指向底层数组的指针,一个是切片的长度,一个是切片的容量

+++

声明和初始化 🔗

slice:=make([]int,5)

使用内置的make函数时,需要传入一个参数,指定切片的长度,例子中我们使用的时5,这时候切片的容量也是5。当然我们也可以单独指定切片的容量。

slice:=make([]int,5,10)

创建的切片长度是5,容量是10,需要注意的这个容量10其实对应的是切片底层数组的。

因为切片的底层是数组,所以创建切片时,如果不指定字面值的话,默认值就是数组的元素的零值。这里我们所以指定了容量是10,但是我们只能访问5个元素,因为切片的长度是5,剩下的5个元素,需要切片扩充后才可以访问。

容量必须>=长度,我们是不能创建长度大于容量的切片的。

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

与创建数组非常像,只不过不用指定[]中的值,这时候切片的长度和容量是相等的,并且会根据我们指定的字面量推导出来

slice:=[]int{4:1}

这是指定了第5个元素为1,其他元素都是默认值0。这时候切片的长度和容量也是一样的

数组和切片的微小差别 🔗

//数组
var arr [5]int
//切片
var slice []int


//数组
array:=[5]int{4:1}
//切片
slice:=[]int{4:1}

nil切片和空切片 🔗

//nil切片
var nilSlice []int
//空切片
slice:=[]int{}

基于现有切片或者数组创建 🔗

slice := []int{1, 2, 3, 4, 5}
slice1 := slice[:]
slice2 := slice[0:]
slice3 := slice[:5]

使用[i:j]这样的操作符即可,她表示以i索引开始,到j索引结束,截取原数组或者切片,创建而成的新切片,新切片的值包含原切片的i索引,但是不包含j索引。slice[i:j)包含i,不包含j 第3个用来限定新切片的容量,其用法为slice[i:j:k],k用来限定切片的容量。

slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:2:3]

一个长度为2-1=1,容量为3-1=2的新切片,不过第三个索引,不能超过原切片的最大索引值5

在函数间传递切片 🔗

func main() {
	slice := []int{1, 2, 3, 4, 5}
	fmt.Printf("%p\n", &slice)
	modify(slice)
	fmt.Println(slice)
}

func modify(slice []int) {
	fmt.Printf("%p\n", &slice)
	slice[1] = 10
}

0xc420082060
0xc420082080
[1 10 3 4 5]

观察发现,这两个切片的地址不一样,所以可以确认切片在函数间传递是复制的。而我们修改一个索引的值后,发现原切片的值也被修改了,说明它们共用一个底层数组。

Tags