go基礎——切片slice
阿新 • • 發佈:2021-10-18
package main import "fmt" /* 切片: 不定長的陣列,是引用型別的資料,指向一個底層陣列。 */ func main() { //切片的建立和訪問 var s1 []int fmt.Println(s1) s2 := []int{1, 2, 3, 4} fmt.Println(s2) s2[0] = 5 fmt.Println(s2) s3 := make([]int, 3) /* make函式可以建立slice,map,chan這三種引用型別 第一個引數是型別,第二個引數是長度len,第三個引數是容量cap(這裡省略了) */ fmt.Println(s3) //切片擴容append s3 = append(s3, 1, 2) fmt.Println(s3) s3 = append(s3, s2...) //append另一個切片中的元素 fmt.Println(s3) //遍歷切片 for i := 0; i < len(s2); i++ { fmt.Println(s2[i]) } for i, v := range s2 { fmt.Println(i, v) } //切片擴容原理 /* 新建一個len=3,cap=3的切片 append兩個值時,這時切片指向一個新的cap=6的底層陣列,並把前一個數組的值複製給新陣列。 元素個數再次增大超過6時,成倍擴容為cap=12。 slice本身不儲存資料,指向的陣列儲存資料,切片變化cap靠改變指向的陣列實現。 */ sli1 := make([]int, 3) fmt.Printf("len:%d,cap:%d,切片地址:%p,陣列地址:%p\n", len(sli1), cap(sli1), &sli1, sli1) sli1 = append(sli1, 1, 2) fmt.Printf("len:%d,cap:%d,切片地址:%p,陣列地址:%p\n", len(sli1), cap(sli1), &sli1, sli1) sli1 = append(sli1, 3, 4) fmt.Printf("len:%d,cap:%d,切片地址:%p,陣列地址:%p\n", len(sli1), cap(sli1), &sli1, sli1) //在已有array上直接建立slice arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sli2 := arr[:5] //1-5 sli3 := arr[3:8] //4-8 sli4 := arr[5:] //6-10 sli5 := arr[:] //1-10 fmt.Println("arr:", arr) fmt.Println("sli2:", sli2) fmt.Printf("len:%d,cap:%d,陣列地址:%p\n", len(sli2), cap(sli2), sli2) fmt.Println("sli3:", sli3) fmt.Printf("len:%d,cap:%d,陣列地址:%p\n", len(sli3), cap(sli3), sli3) fmt.Println("sli4:", sli4) fmt.Printf("len:%d,cap:%d,陣列地址:%p\n", len(sli4), cap(sli4), sli4) fmt.Println("sli5:", sli5) fmt.Printf("len:%d,cap:%d,陣列地址:%p\n", len(sli5), cap(sli5), sli5) //更改陣列或切片內容 fmt.Println("=========更改陣列==========") arr[7] = 100 fmt.Println("arr:", arr) fmt.Println("sli2:", sli2) fmt.Println("sli3:", sli3) fmt.Println("sli4:", sli4) fmt.Println("sli5:", sli5) fmt.Println("=========更改切片==========") sli2[4] = 200 fmt.Println("arr:", arr) fmt.Println("sli2:", sli2) fmt.Println("sli3:", sli3) fmt.Println("sli4:", sli4) fmt.Println("sli5:", sli5) fmt.Println("=========append切片(未超過陣列cap)==========") sli2 = append(sli2, 0, 0, 0) //修改了陣列的5-7位數值 fmt.Println("arr:", arr) fmt.Println("sli2:", sli2) fmt.Println("sli3:", sli3) fmt.Println("sli4:", sli4) fmt.Println("sli5:", sli5) fmt.Println("=========append切片(超過陣列cap)==========") sli4 = append(sli4, 99, 99, 99) //新建了一個底層陣列 sli4[4] = 111 //再修改sli4不會對原陣列有影響了 fmt.Println("arr:", arr) fmt.Println("sli2:", sli2) fmt.Println("sli3:", sli3) fmt.Print("sli4:", sli4) fmt.Printf("\tlen:%d,cap:%d\n", len(sli4), cap(sli4)) fmt.Println("sli5:", sli5) }
執行結果
[] [1 2 3 4] [5 2 3 4] [0 0 0] [0 0 0 1 2] [0 0 0 1 2 5 2 3 4] 5 2 3 4 0 5 1 2 2 3 3 4 len:3,cap:3,切片地址:0xc0000040f0,陣列地址:0xc000012210 len:5,cap:6,切片地址:0xc0000040f0,陣列地址:0xc00000a420 len:7,cap:12,切片地址:0xc0000040f0,陣列地址:0xc00001a1e0 arr: [1 2 3 4 5 6 7 8 9 10] sli2: [1 2 3 4 5] len:5,cap:10,陣列地址:0xc00000c1e0 sli3: [4 5 6 7 8] len:5,cap:7,陣列地址:0xc00000c1f8 sli4: [6 7 8 9 10] len:5,cap:5,陣列地址:0xc00000c208 sli5: [1 2 3 4 5 6 7 8 9 10] len:10,cap:10,陣列地址:0xc00000c1e0 =========更改陣列========== arr: [1 2 3 4 5 6 7 100 9 10] sli2: [1 2 3 4 5] sli3: [4 5 6 7 100] sli4: [6 7 100 9 10] sli5: [1 2 3 4 5 6 7 100 9 10] =========更改切片========== arr: [1 2 3 4 200 6 7 100 9 10] sli2: [1 2 3 4 200] sli3: [4 200 6 7 100] sli4: [6 7 100 9 10] sli5: [1 2 3 4 200 6 7 100 9 10] =========append切片(未超過陣列cap)========== arr: [1 2 3 4 200 0 0 0 9 10] sli2: [1 2 3 4 200 0 0 0] sli3: [4 200 0 0 0] sli4: [0 0 0 9 10] sli5: [1 2 3 4 200 0 0 0 9 10] =========append切片(超過陣列cap)========== arr: [1 2 3 4 200 0 0 0 9 10] sli2: [1 2 3 4 200 0 0 0] sli3: [4 200 0 0 0] sli4:[0 0 0 9 111 99 99 99] len:8,cap:10 sli5: [1 2 3 4 200 0 0 0 9 10]