Go之集合slice的實(shí)現(xià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ù):
slice1:=make([]string,4)
在下面的例子中,指定了新創(chuàng)建的切片 []string 容量為 8:
slice1:=make([]string,4,8)
這里需要注意的是,切片的容量不能比切片的長(zhǎng)度小。
切片的長(zhǎng)度你已經(jīng)知道了,就是切片內(nèi)元素的個(gè)數(shù)。那么容量是什么呢?其實(shí)就是切片的空間。
上面的示例說明,Go 語言在內(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 語言開發(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)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang 實(shí)現(xiàn)超大文件讀取的兩種方法
這篇文章主要介紹了Golang 實(shí)現(xiàn)超大文件讀取的兩種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04MacOS中 VSCode 安裝 GO 插件失敗問題的快速解決方法
這篇文章主要介紹了MacOS中 VSCode 安裝 GO 插件失敗問題的快速解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05一文深入探索Go語言中的循環(huán)結(jié)構(gòu)
在編程中,循環(huán)結(jié)構(gòu)扮演著重要的角色,它使我們能夠有效地重復(fù)執(zhí)行特定的代碼塊,以實(shí)現(xiàn)各種任務(wù)和邏輯,在Go語言中,for 是 Go 中唯一的循環(huán)結(jié)構(gòu),本文將深入探討Go語言中的for循環(huán)類型以及它們的用法2023-08-08基于golang的簡(jiǎn)單分布式延時(shí)隊(duì)列服務(wù)的實(shí)現(xiàn)
這篇文章主要介紹了基于golang的簡(jiǎn)單分布式延時(shí)隊(duì)列服務(wù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02wind10 idea中 go 開發(fā)環(huán)境搭建教程圖解
這篇文章主要介紹了wind10 idea中 go 開發(fā)環(huán)境搭建過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06go責(zé)任鏈行為型設(shè)計(jì)模式Chain?Of?Responsibility
這篇文章主要為大家介紹了go行為型設(shè)計(jì)模式之責(zé)任鏈Chain?Of?Responsibility使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12