【go】陣列and切片

2020-08-11 16:30:48

1.在go中,陣列是值型別

2.陣列定義

var 陣列名 [陣列大小]數據型別
var a [5]int

陣列元素的各個值預設爲0
go中int佔8bytes
陣列的地址,即是陣列第一個元素的地址

3.初始化

	// 4 ways to init arrays
	var arr1 [3]int = [3]int{1, 2, 3}
	fmt.Println(arr1)
	var arr2 = [3]int{1, 2, 3}
	fmt.Println(arr2)

	var arr3 = [...]int{4, 5, 6}
	fmt.Println("arr3=", arr3)
	var arr4 = [...]int{1: 222, 0: 111, 2: 333}
	fmt.Println("arr4=", arr4)

	arr5 := [...]string{1: "tom", 0: "jack",
	 2: "mary"}
	fmt.Println("arr5=", arr5)

4.for-range遍歷

for index, value := range arr{...}

index是陣列下標
value是該位置的值
都是僅在回圈內部的區域性變數
如果不想用,可以直接用忽略_

	var heroes [3]string = [3]string{"宋江",
	"盧俊義", "吳用"}
	for index, value := range heroes {
		fmt.Println(index, value)
	}

5.陣列是相同類型的組合。陣列一旦宣告/定義了,長度就固定了,不能動態變化
長度是型別的一部分

6.var arr []int 這時arr就是一個slice切片
7.陣列中的元素可以是任意型別,包括值型別和參照型別
8.若陣列建立沒有賦值,預設零值
數值型別 0
字串型 「」
bool型 false

9.陣列是值型別,預設值拷貝
如果想在其它函數中修改原來的陣列
用參照傳遞

10.輸出26字母

	var myChars [26]byte
	for i, v := range myChars {
		v = 'A' + byte(i);
		fmt.Printf("%c ", v)
	}

11.golang數據型別必須顯式轉換

12.切片是陣列的一個參照
其使用與陣列類似,遍歷、存取元素、len
slice長度可變,動態變化
定義 var 名 []type

13.入門

	var arr = [...]int{1, 2, 3, 4}
	slice := arr[1: 3] // index range:[1, 3)
	fmt.Println("arr=", arr)
	fmt.Println("slice=", slice)
	fmt.Println("len(slice)=", len(slice))
	// cap可以動態變化
	fmt.Println("slice容量=", cap(slice))

14.slice的記憶體佈局
分爲三部分

指向第一個元素的指針 | len | cap
slice實際是一個struct結構體

15.切片使用的3種方式
1)定義一個切片,讓切片參照已經建立好的陣列
2)make

var name []type = make([]type, len, [cap])
	// slice必須make 不能只宣告
	var slice []float64 = make([]float64, 5, 10)
	fmt.Println(slice)

如果沒由賦值,預設零值
通過make建立的切片對應的陣列由make底層維護,對外不可見。只能通過slice存取各個元素

3)定義一個切片,直接指定具體陣列,

	var slice []float64 = []float64{1, 2, 3}
	fmt.Println(slice)
	fmt.Println("size=", len(slice))
	fmt.Println("cap=", cap(slice))

16.切片參照陣列和make建立的區別
陣列本身程式設計師是否可見

17.切片使用不能越界
18.
var slice = arr[0, end] => var slice = arr[:end]
var slice = arr[start: len(arr)] => var slice = arr[start:]
var slice = arr[0: len(arr)] => var slice = arr[:]

19.切片可以繼續切片

20.append內建函數,動態增加slice元素

	var slice = []int{1, 2, 3}
	slice1 := append(slice, 4, 5, 6)
	fmt.Println("slice =", slice)
	fmt.Println("slice1 =", slice1)

	slice = append(slice, slice...)
	fmt.Println("slice =", slice)

go底層會建立一個新的陣列(按照擴容後的大小)
將原來的值 拷貝到新的陣列
slice重新參照到newArr

21.拷貝操作
copy(slice1, slice2)

	var slice = []int{1, 2, 3}
	var slice1 = make([]int, 10)
	copy(slice1, slice)
	fmt.Println("slice =", slice)
	fmt.Println("slice1 =", slice1)

copy的兩個切片數據空間相互獨立,互不影響
即使拷貝的大小更大也可以

22.string底層是一個byte陣列,因此string也可以做切片處理
string是不可變的,不能通過str[2] = 'z’改變元素的值
如果需要修改
string => []byte/[]rune =>string

	str := "hello@golang"
	arr := []byte(str)
	arr[0] = 'z'
	str = string(arr)
	fmt.Println("str =", str)
	// []byte無法處理漢字
	// []rune可以 按照字元處理 相容漢字