天天看點

Go語言學習筆記——數組與切片(四)

數組(定長數組)

同一資料類型的固定長度的序列。

聲明

var 數組名 [數組長度]元素資料類型
           
  • 數組長度必須是常量,且是類型的組成部分。
  • 數組定義後長度不能變。
  • 數組的類型為

    [數組長度]元素資料類型

    ,長度也是數組類型的一部分。
  • 數組指派為值拷貝。

初始化

一維數組

聲明一個有5個整型變量的數組,預設值都是0

[0 0 0 0 0]

聲明一個有5個整型變量的數組,對前幾個元素指派,未指派的元素為0

//全局變量
var arr1 [5]int = [5]int{1, 2, 3}
//局部變量
arr1 := [5]int{1, 2, 3}
           
[1 2 3 0 0]

聲明一個有5個整型變量的數組,對前所有元素指派

//全局變量
var arr2 [5]int = [5]int{1, 2, 3, 4, 5}
           
[1 2 3 4 5]

聲明一個數組,通過初始化長度和值确定數組類型(元素資料類型和長度)。

//全局變量
var arr3 = [5]int{1, 2, 3, 4, 5}
//局部變量
arr3 := [5]int{1, 2, 3, 4, 5}
           
[1 2 3 4 5]

聲明一個數組,通過初始化值确定數組長度(元素資料類型和長度)。

//全局變量
var arr4 = [...]int{1, 2, 3, 4, 5, 6}
//局部變量
arr4 := [...]int{1, 2, 3, 4, 5, 6}
           
[1 2 3 4 5 6]

聲明一個數組,對指定位置的值指派。

//全局變量
var arr5 = [5]int{3: 3, 4: 4}
//局部變量
arr5 := [5]int{3: 3, 4: 4}
           
[0 0 0 3 4]
多元數組

定義一個全零數組

[[0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0]]

定義一個多元數組并指派

// 全局變量
var arr11 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
var arr12 [2][3]int = [2][3]int{{1, 2, 3}, {7, 8, 9}}
// 局部變量
arr11 := [...][3]int{{1, 2, 3}, {7, 8, 9}}
arr12 := [2][3]int{{1, 2, 3}, {7, 8, 9}}
           

[[1 2 3] [7 8 9]]

[[1 2 3] [7 8 9]]

定義一個多元數組并對指定位置的值指派

// 全局變量
var arr21 [2][3]int = [...][3]int{1: {1: 2}}
var arr22 [2][3]int = [2][3]int{1: {1: 2}}
// 局部變量
arr21 := [...][3]int{1: {1: 2}}
arr22 := [2][3]int{1: {1: 2}}
           

[[0 0 0] [0 2 0]]

[[0 0 0] [0 2 0]]

通路數組元素

通過下标通路

arr0 := [8]int{1, 2, 3, 4}
v1 := arr0[2]
fmt.Println(v1)
           
3
arr00 := [...][3]int{{1, 2, 3}, {4}}
fmt.Println(arr00)
v2 := arr00[1][0]
fmt.Println(v2)
           

[[1 2 3] [4 0 0]]

4

數組的切片

//定義一個數組
arr := [...]int{1, 2, 3, 7, 2, 6, 8, 9, 4}
slice1 := arr[:]
slice2 := arr[2:]
slice3 := arr[:5]
slice4 := arr[2:5]
           

[1 2 3 7 2 6 8 9 4]

[1 2 3 7 2 6 8 9 4]

[3 7 2 6 8 9 4]

[1 2 3 7 2]

[3 7 2]

擷取數組長度

内置函數

len()

cap()

都傳回數組長度 (元素數量)。

arr11 := [...][3]int{{1, 2, 3}, {7, 8, 9}}
// 擷取長度
fmt.Println(len(arr11))
// 擷取容量
fmt.Println(cap(arr11))
           

2

2

周遊數組

一維數組

[1 2 3 4 5 6]

法一:

for i := range arr0 {
	fmt.Print(arr0[i])
}
           
123456

法二:

for i := 0; i < len(arr0); i++ {
	fmt.Print(arr0[i])
}
           
123456

多元數組

法一:

for k1, v1 := range arr00 {
	for k2, v2 := range v1 {
		fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
	}
	fmt.Println()
}
           

(0,0)=1 (0,1)=2 (0,2)=3 (0,3)=0

(1,0)=4 (1,1)=5 (1,2)=6 (1,3)=7

(2,0)=8 (2,1)=9 (2,2)=0 (2,3)=0

法二:

for i := 0; i < len(arr00); i++ {
	for j := 0; j < len(arr00[i]); j++ {
		fmt.Printf("(%d,%d)=%d ", i, j, arr00[i][j])
	}
	fmt.Println()
}
           

(0,0)=1 (0,1)=2 (0,2)=3 (0,3)=0

(1,0)=4 (1,1)=5 (1,2)=6 (1,3)=7

(2,0)=8 (2,1)=9 (2,2)=0 (2,3)=0

切片(變長數組)

切片是數組的一個引用,但它并不是數組或數組指針。

  • 切片是引用類型。
  • 切片的長度可變。
  • 切片的底層是數組。
  • 可以使用切片進行數組的值拷貝,進而解決性能問題。

聲明

var 切片名 []元素資料類型
           
  • 切片不需要說明長度。
  • 使用

    make()

    函數來建立切片時,切片容量可以省略。
  • 切片容量省略時,切片容量=切片長度
  • 切片容量 ≥ 切片長度,切片長度 ≤ 切片容量。
  • 當切片的底層數組不足以容納所有給定值時,它就會配置設定一個更大的數組,切片會指向這個新配置設定的數組。

切片初始化

零切片聲明,零值為

nil

var slice0 []int

// 不推薦
slice0 := []int{}
           
[]

使用

make()

函數初始化切片,預設賦0值

slice1 := make([]int, 5)
fmt.Println(slice1)
slice2 := make([]int, 5, 10)
fmt.Println(slice2)
           

[0 0 0 0 0]

[0 0 0 0 0]

初始化并指派

slice3 := []int{1, 2, 3}
fmt.Println(slice3)
           

利用數組指派

//定義一個數組
arr := [5]int{1, 2, 3, 7}
//定義一個切片
slice4 := make([]int, 5, 10)
//将數組指派給切片(前閉後開區間)
slice4 = arr[0:5]
fmt.Println(slice4)
           
[1 2 3 7 0]

擷取切片長度和容量

// 擷取長度
fmt.Println(len(slice))
// 擷取容量
fmt.Println(cap(slice))
           

切片截取

通過設定上限和下限截取切片(前閉後開區間)

//相當于[0:len(slice)]
slice1 := slice[:]

//相當于[2:len(slice)]
slice2 := slice[2:]

//相當于[0:5]
slice3 := slice[:5]

slice4 := slice[2:5]
           

追加元素

//定義一個切片
sliceA := make([]int, 2, 4)
           
[0 0]

追加單個元素

[0 0 1]

追加多個元素

[0 0 1 2 3 4]

切片拷貝

可以解決數組拷貝造成的性能問題。

//定義一個新的切片
sliceB := make([]int, 10, 20)
//把sliceA的值複制到sliceB
copy(sliceB, sliceA)
fmt.Println(sliceB)
           
[0 0 1 2 3 4 0 0 0 0]

周遊

參考數組的周遊方式