GO學習筆記(3)
阿新 • • 發佈:2020-08-05
三. 切片(slice)
切片:切片是陣列的一個引用,因此切片是引用型別;切片是可變陣列.
3.1. 切片定義
// 建立切片 len()切片的長度 cap()切片的容量 func sliceCreate() { // 宣告 1 var s1 []int fmt.Println(reflect.TypeOf(s1)) // 檢視型別: []int s2 := []string{} fmt.Println(reflect.TypeOf(s2)) // []string // 使用make宣告 s3 := make([]int, 5, 8) fmt.Println(reflect.TypeOf(s3), s3, len(s3),cap(s3))// []int [[0 0 0 0 0] 5 8 // 初始化 s4 := []int{1, 2, 3, 4, 5} fmt.Println(reflect.TypeOf(s4), s4, len(s4),cap(s4)) // []int [1 2 3 4 5] 5 5 // 從陣列中切片 arr := [8]int{1,2,3,4,5,6,7,8} fmt.Println(reflect.TypeOf(arr), len(arr),cap(arr)) // [8]int 8 8 // s5的容量為7,是因為切片只是把起始位置的指標向後移動到start位置,而end位置是保持不變的,以下同理 s5 := arr[1:4] fmt.Println(s5, len(s5),cap(s5)) // [2 3 4] 3 7 s6 := arr[:] fmt.Println(s6, len(s6),cap(s6)) // [1 2 3 4 5 6 7 8] 8 8 s7 := arr[2:] fmt.Println(s7, len(s7),cap(s7)) // [3 4 5 6 7 8] 6 6 s8 := arr[:3] fmt.Println(s8, len(s8),cap(s8)) // [1 2 3] 3 8 s9 := s6[1:3] fmt.Println(s9, len(s9),cap(s9))// [2 3] 2 7 }
3.2. 切片訪問以及追加
func sliceAtc() { // 可用指標直接訪問底層陣列 s1 := make([]int, 5, 8) s1[1] = 2 p := &s1[3] *p = 10 s2 := s1[1:] s2[1] = 30 fmt.Println(s1) // [0 2 30 10 0] // 可直接修改 struct array/slice 成員 d := [5]struct { x int }{} s := d[:] d[1].x = 10 s[2].x = 20 fmt.Println(d) // [{0} {10} {20} {0} {0}] // s 時新開闢的空間,但是s指向的還是底層陣列d fmt.Printf("%p, %p, %p, %p\n", &s, &s[0], &d, &d[0]) // 0xc0000044e0, 0xc0000103c0, 0xc0000103c0, 0xc0000103c0 // 想切片中新增元素 append() a := make([]int, 3, 5) // 追加一個元素後,容量在a.cap()範圍內,則底層陣列不變,返回的slice依然指向原底層陣列 b := append(a, 1) fmt.Println(a, len(a), cap(a)) // [0 0 0] 3 5 fmt.Println(b, len(b), cap(b)) // [0 0 0 1] 4 5 // 超出b的容量,會重新分配底層陣列 c := append(b, a...) fmt.Println(c, len(c), cap(c)) // [0 0 0 1 0 0 0] 7 10 fmt.Println(&a[0], &b[0], &c[0]) // 0xc000010450 0xc000010450 0xc000014190 }