目錄
- Slice(切片)
- 基于數(shù)組生成切片
- 切片修改
- 切片聲明
- Append
- 切片元素循環(huán)
Slice(切片)
切片和數(shù)組類似,可以把它理解為動(dòng)態(tài)數(shù)組。切片是基于數(shù)組實(shí)現(xiàn)的,它的底層就是一個(gè)數(shù)組。對(duì)數(shù)組任意分隔,就可以得到一個(gè)切片?,F(xiàn)在我們通過一個(gè)例子來更好地理解它,同樣還是基于前面的 array。
基于數(shù)組生成切片
下面代碼中的 array[2:5] 就是獲取一個(gè)切片的操作,它包含從數(shù)組 array 的索引 2 開始到索引 5 結(jié)束的元素:
array:=[5]string{"a","b","c","d","e"}
slice:=array[2:5]
fmt.Println(slice)
注意:這里是包含索引 2,但是不包含索引 5 的元素,即在 : 右邊的數(shù)字不會(huì)被包含。
//基于數(shù)組生成切片,包含索引start,但是不包含索引end
slice:=array[start:end]
所以 array[2:5] 獲取到的是 c、d、e 這三個(gè)元素,然后這三個(gè)元素作為一個(gè)切片賦值給變量 slice。
切片和數(shù)組一樣,也可以通過索引定位元素。這里以新獲取的 slice 切片為例,slice[0] 的值為 c,slice[1] 的值為 d。
有沒有發(fā)現(xiàn),在數(shù)組 array 中,元素 c 的索引其實(shí)是 2,但是對(duì)數(shù)組切片后,在新生成的切片 slice 中,它的索引是 0,這就是切片。雖然切片底層用的也是 array 數(shù)組,但是經(jīng)過切片后,切片的索引范圍改變了。
通過下圖可以看出,切片是一個(gè)具備三個(gè)字段的數(shù)據(jù)結(jié)構(gòu),分別是指向數(shù)組的指針 data,長(zhǎng)度 len 和容量 cap:

這里有一些小技巧,切片表達(dá)式 array[start:end] 中的 start 和 end 索引都是可以省略的,如果省略 start,那么 start 的值默認(rèn)為 0,如果省略 end,那么 end 的默認(rèn)值為數(shù)組的長(zhǎng)度。如下面的示例:
- array[:4] 等價(jià)于 array[0:4]。
- array[1:] 等價(jià)于 array[1:5]。
- array[:] 等價(jià)于 array[0:5]。
切片修改
切片的值也可以被修改,這里也同時(shí)可以證明切片的底層是數(shù)組。
對(duì)切片相應(yīng)的索引元素賦值就是修改,在下面的代碼中,把切片 slice 索引 1 的值修改為 f,然后打印輸出數(shù)組 array:
slice:=array[2:5]
slice[1] ="f"
fmt.Println(array)
可以看到如下結(jié)果:
[a b c f e]
數(shù)組對(duì)應(yīng)的值已經(jīng)被修改為 f,所以這也證明了基于數(shù)組的切片,使用的底層數(shù)組還是原來的數(shù)組,一旦修改切片的元素值,那么底層數(shù)組對(duì)應(yīng)的值也會(huì)被修改。
切片聲明
除了可以從一個(gè)數(shù)組得到切片外,還可以聲明切片,比較簡(jiǎn)單的是使用 make 函數(shù)。
下面的代碼是聲明了一個(gè)元素類型為 string 的切片,長(zhǎng)度是 4,make 函數(shù)還可以傳入一個(gè)容量參數(shù):
在下面的例子中,指定了新創(chuàng)建的切片 []string 容量為 8:
slice1:=make([]string,4,8)
這里需要注意的是,切片的容量不能比切片的長(zhǎng)度小。
切片的長(zhǎng)度你已經(jīng)知道了,就是切片內(nèi)元素的個(gè)數(shù)。那么容量是什么呢?其實(shí)就是切片的空間。
上面的示例說明,Go 語(yǔ)言在內(nèi)存上劃分了一塊容量為 8 的內(nèi)容空間(容量為 8),但是只有 4 個(gè)內(nèi)存空間才有元素(長(zhǎng)度為 4),其他的內(nèi)存空間處于空閑狀態(tài),當(dāng)通過 append 函數(shù)往切片中追加元素的時(shí)候,會(huì)追加到空閑的內(nèi)存上,當(dāng)切片的長(zhǎng)度要超過容量的時(shí)候,會(huì)進(jìn)行擴(kuò)容。
切片不僅可以通過 make 函數(shù)聲明,也可以通過字面量的方式聲明和初始化,如下所示:
slice1:=[]string{"a","b","c","d","e"}
fmt.Println(len(slice1),cap(slice1))
可以注意到,切片和數(shù)組的字面量初始化方式,差別就是中括號(hào) [] 里的長(zhǎng)度。此外,通過字面量初始化的切片,長(zhǎng)度和容量相同。
Append
我們可以通過內(nèi)置的 append 函數(shù)對(duì)一個(gè)切片追加元素,返回新切片,如下面的代碼所示:
//追加一個(gè)元素
slice2:=append(slice1,"f")
//多加多個(gè)元素
slice2:=append(slice1,"f","g")
//追加另一個(gè)切片
slice2:=append(slice1,slice...)
append 函數(shù)可以有以上三種操作,你可以根據(jù)自己的實(shí)際需求進(jìn)行選擇,append 會(huì)自動(dòng)處理切片容量不足需要擴(kuò)容的問題。
小技巧:在創(chuàng)建新切片的時(shí)候,最好要讓新切片的長(zhǎng)度和容量一樣,這樣在追加操作的時(shí)候就會(huì)生成新的底層數(shù)組,從而和原有數(shù)組分離,就不會(huì)因?yàn)楣灿玫讓訑?shù)組導(dǎo)致修改內(nèi)容的時(shí)候影響多個(gè)切片。
切片元素循環(huán)
切片的循環(huán)和數(shù)組一模一樣,常用的也是 for range 方式,這里就不再進(jìn)行舉例,當(dāng)作練習(xí)題留給你。
在 Go 語(yǔ)言開發(fā)中,切片是使用最多的,尤其是作為函數(shù)的參數(shù)時(shí),相比數(shù)組,通常會(huì)優(yōu)先選擇切片,因?yàn)樗咝В瑑?nèi)存占用小。
到此這篇關(guān)于Go之集合slice的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go 集合slice內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 使用go操作redis的有序集合(zset)
- MongoDB基礎(chǔ)入門之創(chuàng)建、刪除集合操作
- Go語(yǔ)言之自定義集合Set
- MongoDB在不同主機(jī)間復(fù)制數(shù)據(jù)庫(kù)和集合的教程
- 詳解MongoDB中創(chuàng)建集合與刪除集合的操作方法