1. 程式人生 > 其它 >go基礎——切片slice

go基礎——切片slice

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]