切片底層
切片(Slice)是一個(gè)擁有相同類型元素的可變長度的序列。它是基于數(shù)組類型做的一層封裝。它非常靈活,支持自動(dòng)擴(kuò)容。
切片是一個(gè)引用類型,它的內(nèi)部結(jié)構(gòu)包含地址
、長度
和容量
。切片一般用于快速地操作一塊數(shù)據(jù)集合。
切片的本質(zhì)
切片的本質(zhì)就是對(duì)底層數(shù)組的封裝,它包含了三個(gè)信息:底層數(shù)組的指針、切片的長度(len)和切片的容量(cap)。
舉個(gè)例子,現(xiàn)在有一個(gè)數(shù)組a := [8]int{0, 1, 2, 3, 4, 5, 6, 7}
,切片s1 := a[:5]
,相應(yīng)示意圖如下。
切片s2 := a[3:6]
,相應(yīng)示意圖如下:
切片不能直接比較
切片之間是不能比較的,我們不能使用==
操作符來判斷兩個(gè)切片是否含有全部相等元素。 切片唯一合法的比較操作是和nil
比較。 一個(gè)nil
值的切片并沒有底層數(shù)組,一個(gè)nil
值的切片的長度和容量都是0。但是我們不能說一個(gè)長度和容量都是0的切片一定是nil
,例如下面的示例:
var s1 []int //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{} //len(s2)=0;cap(s2)=0;s2!=nil
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil
所以要判斷一個(gè)切片是否是空的,要是用len(s) == 0
來判斷,不應(yīng)該使用s == nil
來判斷。
切片的擴(kuò)容策略
- 首先判斷,如果新申請(qǐng)容量(cap)大于2倍的舊容量(old.cap),最終容量(newcap)就是新申請(qǐng)的容量(cap)。
- 否則判斷,如果舊切片的長度小于1024,則最終容量(newcap)就是舊容量(old.cap)的兩倍,即(newcap=doublecap),
- 否則判斷,如果舊切片長度大于等于1024,則最終容量(newcap)從舊容量(old.cap)開始循環(huán)增加原來的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最終容量(newcap)大于等于新申請(qǐng)的容量(cap),即(newcap >= cap)
- 如果最終容量(cap)計(jì)算值溢出,則最終容量(cap)就是新申請(qǐng)容量(cap)。
需要注意的是,切片擴(kuò)容還會(huì)根據(jù)切片中元素的類型不同而做不同的處理,比如int
和string
類型的處理方式就不一樣。
使用copy()函數(shù)復(fù)制切片
由于切片是引用類型,所以a和b其實(shí)都指向了同一塊內(nèi)存地址。修改b的同時(shí)a的值也會(huì)發(fā)生變化。
Go語言內(nèi)建的copy()
函數(shù)可以迅速地將一個(gè)切片的數(shù)據(jù)復(fù)制到另外一個(gè)切片空間中,copy()
函數(shù)的使用格式如下:
copy(destSlice, srcSlice []T)
其中:
- srcSlice: 數(shù)據(jù)來源切片
- destSlice: 目標(biāo)切片
從切片中刪除元素
Go語言中并沒有刪除切片元素的專用方法,我們可以使用切片本身的特性來刪除元素。 代碼如下:
func main() {
// 從切片中刪除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要?jiǎng)h除索引為2的元素
a = append(a[:2], a[3:]...)
fmt.Println(a) //[30 31 33 34 35 36 37]
}
總結(jié)一下就是:要從切片a中刪除索引為index
的元素,操作方法是a = append(a[:index], a[index+1:]...)
文章來源:http://www.zghlxwxcb.cn/news/detail-674068.html
package main
import "fmt"
func main() {
var a = make([]string, 5, 10)
for i := 0; i < 10; i++ {
a = append(a, fmt.Sprintf("%v", i))
}
fmt.Println(a)
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-674068.html
到了這里,關(guān)于go語言中的切片的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!