前言:
由於工做須要,最近接觸 Golang 比較多。
也但願本身的技術棧能從一個 iOS 轉變成 iOS / Golang。golang
那麼,今天咱們來聊一聊Golang中的數組(Array
)和切片(Slice
)。數組
數組咱們確定都是熟悉的,
在Go語言中數組(Array
)在初始化後,長度是固定的。bash
與其餘語言相似,在這裏舉一些在Go中數組的簡單demo。app
var arr [10]int // 聲明,len與cap爲10,值默認補0。
arr := []int {1,2,3,4} // 快速聲明,len與cap爲4,值爲[1,2,3,4]。
arr := [5]int {1,2,3,4} // 快速聲明,len與cap爲5,值爲[1,2,3,4,0],末尾默認補0。
// 數組的遍歷
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
複製代碼
接下來是今天的主角:Slice。ui
首先,切片是一種引用類型。(與字典map
、通道channel
同樣,都是引用類型)
有點相似於咱們iOS中的MutableArray
。
暫時可理解爲一種可變長的「動態數組」。spa
注意:
所以,咱們取數組的切片時,若是不但願切片的修改會對原有數組產生影響的話,須要對Slice
進行Copy
操做。code
numbers := []int{1,2,3,4,5,6,7,8,9,10}
// 半閉半開結構
slice1 := numbers[:] // 直接對numbers的引用
slice1 = numbers[1:10] // 從numbers[1]到numbers[9]
slice1 = numbers[:5] // 從開始到numbers[4]
slice1 = numbers[7:] // 從numbers[7]開始到末尾
slice1 = append(slice1, 1,2,3,4,5) // 追加長度
fmt.Println(slice1) // 打印:[8 9 10 1 2 3 4 5]
slice2 := make([]int, len(slice1), cap(slice1)*2) // 手動聲明一個slice2,最大長度cap爲slice1的兩倍。
copy(slice2,slice1) //將slice1的數據copy到slice2
slice2 = append(slice2,1,2,3) // 在對slice2進行追加
fmt.Println(slice1) // 打印:[8 9 10 1 2 3 4 5]
fmt.Println(slice2) // 打印:[8 9 10 1 2 3 4 5 1 2 3]
fmt.Printf("len = %d, cap = %d", len(slice1), cap(slice1)) // 打印當前長度len,與最大容量cap。
複製代碼
當Slice
的長度(len
)即將超過最大容量(cap
)時,Go語言會對Slice
進行擴容。string
具體策略爲:table
Slice
的長度(len
)小於1024
時,Go語言會對該Slice
進行 「2倍」擴容 。Slice
的長度(len
)大於等於1024
時,Go語言會對該Slice
進行 「1.25倍」擴容 。len | 擴容策略 |
---|---|
<1024 | 2倍擴容 |
>=1024 | 1.25倍擴容 |
感興趣的同窗,可使用下面的代碼,本身試一下它的擴容策略。class
slice2 := make([]int,10,10)
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印當前長度len,與最大容量cap。 // 獲取len與cap的長度。
slice2 = append(slice2, 1,2,3,4,5) // 追加數據
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印當前長度len,與最大容量cap。 // 獲取len與cap的長度。
複製代碼
切記切記,切片是一種引用類型。若是改切片的值不但願改動原有數據,必定要先copy一份。
對切片的遍歷時,系統會對value進行一次值拷貝。所以不能對value進行引用操做,不然可能會形成panic。若是須要引用操做,請去下標。