在實際開發中,大多數狀況處理的數據都不是單一的,而是複數的同類型數據。全部的高級語言都會封裝相應的數據結構、API等。在Go語言中,提供了數組、切片以及映射三種數據結構供開發者管理和處理集合數據。切片基於數組,卻有別於數組,本次筆記學習Go切片相關的內容。數組
爲了更方便學習切片的內容,首先簡單瞭解一下切片的底層長什麼樣。 安全
由上圖,一個切片有三個項,長度,容量以及指向數組的指針,即切片是創建在數組的基礎上的。建立切片時,底層的數組容量爲切片的指定容量,切片在使用時,可用的空間只有切片指定長度的空間。設置容量爲底層的數組提供一層保護。當切片動態增加時,纔會影響切片的容量。使用內置數據結構的第一步:聲明建立初始化。 切片有三種建立方式 使用make建立切片數據結構
//語法: make([]切片類型, 長度, 容量) 其中容量爲可選值,容量>=長度
//建立一個長度爲5,容量爲10的整形切片
intSlice := make([]int, 5, 10)
//若是不指定容量值,則生成長度與容量相等的切片
//建立一個長度爲10,容量爲10的字符串切片
stringSlice := make([]string, 10)
複製代碼
PS: make函數也可用於建立map及channel,如有寫到相關內容再細聊。app
訪問與修改切片元素與數組一致函數
intSlice[2] = 3
stringSlice[4] = "ji ni tai mei"
//未賦值的元素爲默認零值
/* 若是訪問的索引超過切片長度,編譯會產生 index out of range越界異常,如 fmt.Println(intSlice[5]) */
複製代碼
聲明並初始化學習
//語法: []類型{初始化元素列表, ...}
//建立一個長度爲4,容量爲4的字符串切片
stringSlice := []string{"red", "yellow", "blue", "green"}
//建立一個空切片
nilSlice := []int{}
複製代碼
請注意此方式與建立數組的區別,當中括號有具體數值時表示建立數組。ui
//建立一個有初始化元素的字符串數組
stringArr := [5]string{"red", "yellow", "blue", "green"}
複製代碼
也能夠指定長度。spa
//建立長度和容量爲10的字符串切片
stringSlice := []string{9: "rainbow"}
複製代碼
從一個切片中建立切片指針
slice := []int{1, 2, 3, 4, 5, 6}
//語法: 原切片[i:j:容量] //容量爲可選,不指定時標識到原切片末尾
newSlice := slice[1:4] //newSlice爲 [2, 3, 4]
複製代碼
以上建立了一個長度爲3,容量爲5的切片。注意此處切片的長度爲j-i
,j不是結束元素的索引。 前面瞭解了切片的底層,用此種方式建立的切片的會共享底層的數組,能夠理解爲,「從切片中切片」,那麼修改切片會相互受到影響。code
slice[2] = 99
fmt.Println(newSlice[1]) //結果輸出99
複製代碼
從切片中切片↓
相較於數組,切片的一個優點是能夠動態增加。經過append()
增加切片。 在此以前,瞭解一下兩個內置函數len()
和cap()
,前者返回切片的長度,後者返回切片的容量。
//寫個簡單的函數輸出切片長度、容量和內容
func echoStringSlice(slice []string) {
fmt.Printf("len: %d\n", len(slice))
fmt.Printf("cap: %d\n", cap(slice))
fmt.Println(slice)
}
//語法: append(原切片, ...新增原始) //第二參數爲可變參數,能夠添加任意多個
func main() {
stringSlice := []string{"red", "yellow", "blue", "green"}
echoStringSlice(stringSlice)
fmt.Println("After append...")
newSlice := append(stringSlice, "rainbow")
echoStringSlice(newSlice)
}
複製代碼
編譯運行後,結果爲
len: 4
cap: 4
[red yellow blue green]
After append...
len: 5
cap: 8
[red yellow blue green rainbow]
複製代碼
經過append()
函數會新生成一個切片,新生成的切片長度增加了,當切片的容量足夠添加新的元素時,容量並不會發生改變,僅僅只是切片的長度變化,而當容量不足時則會動態增加底層數組,新生成的切片容量爲原來的兩倍(原容量小於1024時, 不然按增加因子0.25增加相應容量,隨着數值的上升,增加因子可能會變得更小)
在函數間傳遞切片的空間開銷是很小的。前面簡單瞭解了切片的底層結構,那麼在函數間傳遞切片時,切片在傳遞時大概只有一個指針、兩個整形加起來那麼大。而函數間傳遞數組時,須要複製整一個數組,對各方面的開銷都是比較巨大的,固然也能夠用指針來傳遞,但對指針操做稍不注意可能就會出現安全問題,且想要動態增加也沒那麼方便了。