1. 程式人生 > >【go語言 基礎系列】陣列及slice

【go語言 基礎系列】陣列及slice

【陣列】

Go語言處理陣列特別的地方是:go把陣列看成是值傳遞
如果需要傳引用,需要額外處理  *[5]int  

如下demo

package main

import (
	"fmt"
)

func main() {
	var arr1 = [5]int{1, 2, 3, 4, 5}
	var arr2 = [5]int{1, 2, 3, 4, 5}
	fmt.Println("arr1 is:", arr1)

	dealarr(arr1)
	fmt.Println("arr1 is:", arr1)

	// *[5]int p

	fmt.Println("arr2 is:", arr2)
	dealp(&arr2) //通過& 來獲取指標傳遞引數
	fmt.Println("arr2 is:", arr2)
}

func dealarr(a [5]int) {
	a[0] = 55
	fmt.Println(" a is:", a)
}

func dealp(b *[5]int) {
	b[0] = 66
	fmt.Println("b is", b)
}

執行結果如下:

arr1 is: [1 2 3 4 5]
 a is: [55 2 3 4 5]
arr1 is: [1 2 3 4 5]
arr2 is: [1 2 3 4 5]
b is &[66 2 3 4 5]
arr2 is: [66 2 3 4 5]
【slice】

slice的程式碼定義在runtime下的 slice.go中,其型別如下

type slice struct {
        array unsafe.Pointer
        len   int
        cap   int
}

是一個有三個元素的struct

  1. array 為指標,指向陣列的可以從slice中訪問的第一個元素
  2. len 為長度,slice中元素的個數
  3. cap為容量,從slice的的起始元素(即指標)到底層陣列最後一個元素間的個數

檢測一個slice是否為空  使用len(slice1)==0.

更多demo如下

package main

import (
	"fmt"
)

func main() {
	var arr = [10]string{"a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9", "j10"}
	fmt.Printf("arr type is %T,\nvalue is %v\n", arr, arr)
	fmt.Println("len(arr) is:", len(arr))

	s1 := arr[1:1]

	fmt.Println("s1: arr[1:1]", s1, "len is:", len(s1), "cap is:", cap(s1))

	s2 := arr[2:5]
	fmt.Println("s2: arr[2:5]", s2, "len is:", len(s2), "cap is:", cap(s2))

	s3 := arr[5:]
	fmt.Println("s3: arr[5:]", s3, "len is:", len(s3), "cap is:", cap(s3))

	s4 := arr[:5]
	fmt.Println("s4: arr[:5]", s4, "len is:", len(s4), "cap is:", cap(s4))

	s5 := arr[:]
	fmt.Println("s5: arr[:]", s5, "len is:", len(s5), "cap is:", cap(s5))

	s6 := arr[7:8]
	fmt.Println("s6: arr[7:8]", s6, "len is:", len(s6), "cap is:", cap(s6))

	s7 := arr[2:8]
	fmt.Println("s7 is: arr[2:8]", s7)
   //使用 range 來遍歷下標及value
	for i, j := range s7 {   
		fmt.Println("i is", i, "j is:", j)
	}
}

執行結果如下,可以體會出 len  cap 及指標的實際意義。

arr type is [10]string,
value is [a1 b2 c3 d4 e5 f6 g7 h8 i9 j10]
len(arr) is: 10
s1: arr[1:1] [] len is: 0 cap is: 9
s2: arr[2:5] [c3 d4 e5] len is: 3 cap is: 8
s3: arr[5:] [f6 g7 h8 i9 j10] len is: 5 cap is: 5
s4: arr[:5] [a1 b2 c3 d4 e5] len is: 5 cap is: 10
s5: arr[:] [a1 b2 c3 d4 e5 f6 g7 h8 i9 j10] len is: 10 cap is: 10
s6: arr[7:8] [h8] len is: 1 cap is: 3
s7 is: arr[2:8] [c3 d4 e5 f6 g7 h8]
i is 0 j is: c3
i is 1 j is: d4
i is 2 j is: e5
i is 3 j is: f6
i is 4 j is: g7
i is 5 j is: h8


【陣列與slice】

slice依賴一個底層的陣列,下面的例子在同個底層陣列上建立了2 個slice,分別通過更改陣列的值,slice的值 來對比全域性的資料變化,最後演示了 append()內建函式的呼叫demo,可以看到 在slice中append資料,在容量允許的情況下會修改底層陣列的值。

package main

import (
	"fmt"
)

func main() {
	var arr1 = [10]string{"z0", "a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9"}
	slice1 := arr1[0:4]
	slice2 := arr1[2:6]
    //注意兩個slice中的共同元素 
    //注意元素個數與切片數值的管理
	fmt.Println("slice1 arr1[0:4]:", slice1)
	fmt.Println("slice2 arr1[2:6]:", slice2)
    
     //直接修改底層陣列來看slice的變化
	fmt.Println("arr1[2] is:", arr1[2])
	arr1[2] = "BB22"  
	fmt.Println("arr1[2] is:", arr1[2])
	fmt.Println("now  arr1 is:", arr1)
	fmt.Println("slice1 arr1[0:4]:", slice1)
	fmt.Println("slice2 arr1[2:6]:", slice2)

     //直接修改其中slice1的第四個元素
	fmt.Println("slice1[3] is:", slice1[3])
	slice1[3] = "Cnew"
	fmt.Println("slice1[3] is:", slice1[3])
	fmt.Println("### after change slice1[3]")
    //修改slice1 後觀察底層陣列及 slice2的變化
	fmt.Println("arr1 is:", arr1)
	fmt.Println("slice1 arr1[0:4]:", slice1)
	fmt.Println("slice2 arr1[2:6]:", slice2)
    //append 對資料的影響
	slicenew := append(slice1, "from_append")
	fmt.Println("arr1 is:", arr1)
	fmt.Println("slice1 arr1[0:4]:", slice1)
	fmt.Println("slice2 arr1[2:6]:", slice2)
	fmt.Println("slicenew is:", slicenew)

}

執行結果如下

slice1 arr1[0:4]: [z0 a1 b2 c3]
slice2 arr1[2:6]: [b2 c3 d4 e5]
arr1[2] is: b2
arr1[2] is: BB22
now  arr1 is: [z0 a1 BB22 c3 d4 e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 c3]
slice2 arr1[2:6]: [BB22 c3 d4 e5]
slice1[3] is: c3
slice1[3] is: Cnew
### after change slice1[3]
arr1 is: [z0 a1 BB22 Cnew d4 e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 Cnew]
slice2 arr1[2:6]: [BB22 Cnew d4 e5]
arr1 is: [z0 a1 BB22 Cnew from_append e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 Cnew]
slice2 arr1[2:6]: [BB22 Cnew from_append e5]
slicenew is: [z0 a1 BB22 Cnew from_append]