Go學習(十):切片

1。切片的概念

Go語言中陣列的長度不可改變,但在很多應用場景中,在初始定義陣列時,陣列的長度並不可預知,這樣的序列集合無法滿足要求。Go中提供了另外一種內建型別

切片(slice)

,彌補了陣列的缺陷。從底層來看,切片引用了陣列的物件。切片可以追加元素,在追加時可能使切片的容量增大。與陣列相比,切片不需要設定長度,在[]中不用設定值,相對來說比較自由。

2。切片宣告使用

2。1 透過make

//使用make()函式來建立切片var slice1 = make([]int,3)slice1[0] = 1slice1[1] = 2slice1[2] = 4fmt。Printf(“透過make關鍵字[slic1] 型別:%T 值:%v \n”,slice1,slice1)// 輸出: 透過make關鍵字[slic1] 型別:[]int 值:[1 2 4]

2。2 直接初始化

// 直接初始化使用slice2 := []int{1,2,4}fmt。Printf(“直接初始化使用[slic2] 型別:%T 值:%v \n”,slice2,slice2)// 輸出: 直接初始化使用[slic2] 型別:[]int 值:[1 2 4]

2。3 透過陣列擷取

package mainimport “fmt”func main() { // 定義一個數組 arr := [。。。]int{1,2,4,6,8,10,12,14,16} // 從索引0開始擷取到索引為4(不包括4) slice3 := arr[0:4] fmt。Printf(“從索引0開始擷取到索引為4(不包括4)[slice3] 型別:%T 值:%v \n”,slice3,slice3) // 索引從0開始時,0也可以省略不寫 slice33 := arr[:4] fmt。Printf(“從索引0開始擷取到索引為4(不包括4)[slice33] 型別:%T 值:%v \n”,slice33,slice33) // 從索引4開始擷取到最後 slice4 := arr[5:] fmt。Printf(“從索引5開始擷取到最後[slice4] 型別:%T 值:%v \n”,slice4,slice4)}/**輸出從索引0開始擷取到索引為4(不包括4)[slice3] 型別:[]int 值:[1 2 4 6] 從索引0開始擷取到索引為4(不包括4)[slice33] 型別:[]int 值:[1 2 4 6] 從索引5開始擷取到最後[slice4] 型別:[]int 值:[10 12 14 16] */

3。切片刪除

3。1 刪除第一個元素

package mainimport “fmt”func main() { // 定義一個切片 slice := []int{1,2,3,4,5,6} fmt。Printf(“切片slice——> 值:%v len: %d cap: %d\n”,slice,len(slice),cap(slice)) // 刪除第一個元素 slice = slice[1:] fmt。Printf(“刪除一個元素後——> 值:%v len: %d cap: %d\n”,slice,len(slice),cap(slice))}/*輸出切片slice——> 值:[1 2 3 4 5 6] len: 6 cap: 6刪除一個元素後——> 值:[2 3 4 5 6] len: 5 cap: 5*/

3。2 刪除最後一個元素

package mainimport “fmt”func main() { // 定義一個切片 slice := []int{1,2,3,4,5,6} fmt。Printf(“切片slice——> 值:%v len: %d cap: %d\n”,slice,len(slice),cap(slice)) // 刪除最後一個元素 slice = slice[:len(slice)-1] fmt。Printf(“刪除一個元素後——> 值:%v len: %d cap: %d\n”,slice,len(slice),cap(slice))}/*輸出切片slice——> 值:[1 2 3 4 5 6] len: 6 cap: 6刪除一個元素後——> 值:[1 2 3 4 5] len: 5 cap: 6*/

3。3 刪除指定位置元素

package mainimport “fmt”func main() { // 定義一個切片 slice := []int{1,2,3,4} fmt。Printf(“切片slice——> 值:%v len: %d cap: %d\n”,slice,len(slice),cap(slice)) index := 2 // 指定索引前面一部分 front := slice[:index] // 指定索引後面一部分 behind := slice[index+1:] // 拼起來 slice = append(front,behind。。。) fmt。Printf(“刪除索引%d後——> 值:%v len: %d cap: %d\n”,index,slice,len(slice),cap(slice))}

4。len()和cap()

4。1 作用

切片的長度是切片中元素的數量。切片的容量是從建立切片的索引開始的底層陣列中元素的數量。

切片可以透過

len()

方法獲取長度,可以透過

cap()

方法獲取容量。

陣列計算cap()結果與len()相同

4。2 使用

package mainimport “fmt”func main() { // 建立一個切片 slice := []int{1,2,4,6,8,10,12,14,16} fmt。Printf(“切片slice, len:%d cap:%d \n”,len(slice),cap(slice)) // 清空切片slice賦值給slice1 slice1 := slice[0:0] fmt。Printf(“切片slice1, len:%d cap:%d \n”,len(slice1),cap(slice1)) // 使用make指定容量建立切片 var slice2 = make([]int,4,8) slice2[1] = 1 slice2[3] = 3 fmt。Printf(“切片slice2, len:%d cap:%d \n”,len(slice2),cap(slice2)) // 陣列計算cap()結果與len()相同 arr := [。。。]int{1,2,4,6,8,10,12,14,16} fmt。Printf(“陣列arr, len:%d cap:%d \n”,len(arr),cap(arr))}/***輸出:切片slice, len:9 cap:9 切片slice1, len:0 cap:9 切片slice2, len:4 cap:8 陣列arr, len:9 cap:9 */

5。切片是引用型別

切片沒有自己的任何資料。它只是底層陣列的一個引用。對切片所做的任何修改都將反映在底層陣列中。

陣列是值型別,而切片是引用型別。

5。1 函式傳參

package mainimport “fmt”func testSlice(slice []int) { // 修改切片的值 slice[0] = 100}func main() { // 建立一個切片 var slice = make([]int,4,4) slice = []int{1,2,3,4} fmt。Printf(“變數slice 型別: %T 記憶體地址: %p 值:%v \n”,slice,&slice,slice) // 呼叫函式修改 testSlice(slice) fmt。Printf(“呼叫函式後,變數slice 型別: %T 記憶體地址: %p 值:%v \n”,slice,&slice,slice)}/**輸出變數slice 型別: []int 記憶體地址: 0xc00000c080 值:[1 2 3 4] 呼叫函式後,變數slice 型別: []int 記憶體地址: 0xc00000c080 值:[100 2 3 4] */

5。2 多切片共享

修改切片數值,當多個切片共享相同的底層陣列時,對每個元素所做的更改將在陣列中反映出來。

package mainimport “fmt”func testSlice(slice []int) { // 修改切片的值 slice[0] = 100}func main() { // 建立一個切片 var slice = make([]int, 4, 4) slice = []int{1, 2, 3, 4} fmt。Printf(“變數slice 型別: %T 記憶體地址: %p 值:%v \n”, slice, &slice, slice) // 複製給另外一個切片 sliceCopy := slice fmt。Printf(“變數sliceCopy 型別: %T 記憶體地址: %p 值:%v \n”, sliceCopy, &sliceCopy, sliceCopy) // 從切片中擷取 slice2 := slice[0:2] fmt。Printf(“變數slice2 型別: %T 記憶體地址: %p 值:%v \n”, slice2, &slice2, slice2) // 呼叫函式修改 testSlice(slice) fmt。Printf(“呼叫函式後——-變數slice 型別: %T 記憶體地址: %p 值:%v \n”, slice, &slice, slice) fmt。Printf(“呼叫函式後——-變數sliceCopy 型別: %T 記憶體地址: %p 值:%v \n”, sliceCopy, &sliceCopy, sliceCopy) fmt。Printf(“呼叫函式後——-變數slice2 型別: %T 記憶體地址: %p 值:%v \n”, slice2, &slice2, slice2)}

6。append()和copy()

6。1 作用

append()

:用於往切片中追加新元素,可以向切片裡面追加一個或者多個元素,也可以追加一個切片。

copy()

: 不會建立源切片與目標切片之間的聯絡。也就是兩個切片不存在聯絡,其中一個修改不影響另一個。

6。2 使用append()

package mainimport “fmt”func testSlice(slice []int) { // 修改切片的值 slice[0] = 100}func main() { // 定義一個切片型別,長度為0,容量為4 var slice = make([]int, 0, 4) //向切片中新增1個元素 (不超過容量) slice1 := append(slice,1) fmt。Printf(“變數slice1 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice1,len(slice1),cap(slice1),&slice1 ) // 向切片中新增多個元素(不超過容量) slice2 := append(slice,3,4,5) fmt。Printf(“變數slice2 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice2,len(slice2),cap(slice2),&slice2 ) // 向切片中新增一個切片(超過容量) newSlice := []int{1,2,3,4,5,6,7} slice3 := append(slice,newSlice[:]。。。) fmt。Printf(“變數slice3 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice3,len(slice3),cap(slice3),&slice3 ) // 呼叫函式修改 testSlice(slice1) fmt。Printf(“呼叫函式後-變數slice1 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice1,len(slice1),cap(slice1),&slice1 ) fmt。Printf(“呼叫函式後-變數slice2 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice2,len(slice2),cap(slice2),&slice2 ) fmt。Printf(“呼叫函式後-變數slice3 ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice3,len(slice3),cap(slice3),&slice3 )}/**輸出變數slice1 ——- 值: [1] 長度(len):1 容量(cap): 4 地址: 0xc00000c080 變數slice2 ——- 值: [3 4 5] 長度(len):3 容量(cap): 4 地址: 0xc00000c0c0 變數slice3 ——- 值: [1 2 3 4 5 6 7] 長度(len):7 容量(cap): 8 地址: 0xc00000c100 呼叫函式後-變數slice1 ——- 值: [100] 長度(len):1 容量(cap): 4 地址: 0xc00000c080 呼叫函式後-變數slice2 ——- 值: [100 4 5] 長度(len):3 容量(cap): 4 地址: 0xc00000c0c0 呼叫函式後-變數slice3 ——- 值: [1 2 3 4 5 6 7] 長度(len):7 容量(cap): 8 地址: 0xc00000c100 */

append()會改變切片所引用的陣列的內容,從而影響到引用同一陣列的其他切片。

當使用

append()

追加元素到切片時,如果容量不夠(也就是(cap-len) == 0),Go就會建立一個新的記憶體地址來儲存元素。

6。3 使用copy()

package mainimport “fmt”func main() { // 定義一個切片 slice := []int{1,2,3,4} fmt。Printf(“變數slice ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice,len(slice),cap(slice),&slice ) // 定義一個切片變數用來複制slice copySlice := make([]int,8) // 使用copy count := copy(copySlice,slice) fmt。Printf(“複製的數量: %d \n”,count) fmt。Printf(“變數copySlice ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, copySlice,len(copySlice),cap(copySlice),©Slice ) // 修改複製後的切片,源切片不會變 copySlice[0] = 100 fmt。Printf(“修改後——>變數slice ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, slice,len(slice),cap(slice),&slice ) fmt。Printf(“修改後——>變數copySlice ——- 值: %v 長度(len):%d 容量(cap): %d 地址: %p \n”, copySlice,len(copySlice),cap(copySlice),©Slice )}/**輸出變數slice ——- 值: [1 2 3 4] 長度(len):4 容量(cap): 4 地址: 0xc00000c080 複製的數量: 4 變數copySlice ——- 值: [1 2 3 4 0 0 0 0] 長度(len):8 容量(cap): 8 地址: 0xc00000c0c0 修改後——>變數slice ——- 值: [1 2 3 4] 長度(len):4 容量(cap): 4 地址: 0xc00000c080 修改後——>變數copySlice ——- 值: [100 2 3 4 0 0 0 0] 長度(len):8 容量(cap): 8 地址: 0xc00000c0c0 */

微信搜尋【猿碼記】,獲取最新文章資訊。[得意]