首页>>后端>>Golang->如何理解go语言的slice

如何理解go语言的slice

时间:2023-11-30 本站 点击:0

Go语言中的slice,通俗的来说就是动态的数组;我们都知道,数组的长度是固定的,一旦声明后,数组的长度是固定的;但是slice的长度是不固定的,声明后,仍然可以继续增加slice的长度,我们先看一下slice的数据结构是怎样的。

typeslicestruct{arrayunsafe.Pointerlenintcapint}

如上所示:

array是数组的一个指针

len是当前切片的元素个数

cap表示当前切片的容量(即最大可以容纳多少个元素)

array指向的地方是一块连续的内存空间,存储切片的元素;连续的内存空间+长度+容量组成了切片,这里可以看成是数组的一个抽象,因为如果len和cap保持不变,slice本质就是一个数组;但slice和cap会发生变化,所以这就是切片。

切片的声明:

m:=[]int{1,2,3}m:=make([]int,3)

如果我们要获取切片的一部分,可以这样

m:=[]int{1,2,3}n0:=m[0:2]//输出[1,2]n1:=m[:2]//输出[1,2]

通过m[start:end]的方式获取切片的一部分,包含start不包含end,也可以不写start, m[:2]表示从开始到原切片下标为1的元素为止,不写end,m[1:]表示从下标为1的元素开始到原切片元素结束为止。\ \ 我们下面再看一道有意思的代码,再理解下slice:

funcmain(){m:=[]int{1,2,3}n:=m[:2]n=append(n,4)n=append(n,5)n=append(n,6)fmt.Printf("%v\n",m)n[0]=7fmt.Printf("%v",m)}

上面的代码会输出什么呢.一开始是不是会觉得第一个输出是:[1,2,4,5,6]\ 第二个输出是:[7,2,4,5,6]

正确答案肯定不是的,这里的正确输出两个都是:[1,2,4]

why?\ 我们一行行的来分析这段代码\

首先:m := []int{1, 2, 3},已经限定了m的len是3, cap是3。

n := m[:2],n变成[1,2], m依旧是[1,2,3],n引用了m的一部分,n的len是2,cap是3。

n = append(n, 4), n变成[1,2,4],m变成了[1,2,4],因为n,m指向的同一块连续空间,n修改了第三个元素,m也会跟着变化。

n = append(n, 5),n的容量是3,这个时候发现容量不够了,需要扩容,扩容两倍,cap变成6,扩容后开辟了一个新的连续内存空间,此时,n与m已经没有关系了,所以不管后面n如何再append元素或者改变元素,都与m没有关系了。

那么两个输出都是[1,2,4]。

这里我们了解到slice的扩容机制:当cap不够的时候,如果slice的元素个数小于1024个扩大两倍;如果元素大于1024个,扩大1.25倍,并且每次扩容后会变成一个新的切片。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4601.html