基本概念
在 Go 語言中,陣列(Array)是一種固定長度的、相同型別的元素序列。陣列的長度在宣告時就已經確定,並且不能改變。陣列的每個元素可以透過索引訪問,索引從 0 開始。
陣列的宣告和初始化:
在 Go 語言中,陣列的宣告和初始化有多種方式,以下是幾種常見的方式:
1. 宣告並初始化陣列
方式一:使用 var
關鍵字宣告並初始化
var arr [5]int = [5]int{1, 2, 3, 4, 5}
方式二:使用短變數宣告並初始化
arr := [5]int{1, 2, 3, 4, 5}
2. 宣告陣列但不初始化
var arr [5]int
這種方式宣告的陣列,所有元素會被初始化為該型別的零值(例如,int
型別的零值是 0
)。
3. 使用省略號 ...
自動推斷陣列長度
arr := [...]int{1, 2, 3, 4, 5}
這種方式會根據初始化列表中的元素個數自動推斷陣列的長度。
4. 部分初始化陣列
arr := [5]int{1, 2}
這種方式會初始化前兩個元素為 1
和 2
,其餘元素會被初始化為零值。
5. 指定索引初始化陣列
css程式碼解讀複製程式碼arr := [5]int{0: 1, 4: 5}
這種方式會初始化索引為 0
的元素為 1
,索引為 4
的元素為 5
,其餘元素會被初始化為零值。
6. 多維陣列的宣告和初始化
var arr [2][3]int arr := [2][3]int{{1, 2, 3}, {4, 5, 6}}
多維陣列的宣告和初始化與一維陣列類似,只是巢狀了更多的維度。
示例程式碼:
package main import "fmt" func main() { // 方式一:使用 var 關鍵字宣告並初始化 var arr1 [5]int = [5]int{1, 2, 3, 4, 5} fmt.Println(arr1) // 方式二:使用短變數宣告並初始化 arr2 := [5]int{1, 2, 3, 4, 5} fmt.Println(arr2) // 方式三:宣告陣列但不初始化 var arr3 [5]int fmt.Println(arr3) // 方式四:使用省略號自動推斷陣列長度 arr4 := [...]int{1, 2, 3, 4, 5} fmt.Println(arr4) // 方式五:部分初始化陣列 arr5 := [5]int{1, 2} fmt.Println(arr5) // 方式六:指定索引初始化陣列 arr6 := [5]int{0: 1, 4: 5} fmt.Println(arr6) // 方式七:多維陣列的宣告和初始化 var arr7 [2][3]int arr8 := [2][3]int{{1, 2, 3}, {4, 5, 6}} fmt.Println(arr7) fmt.Println(arr8) }
陣列的記憶體分析:
在 Go 語言中,陣列的記憶體分配和佈局相對簡單且直觀。陣列是一個固定長度的、相同型別的元素序列,其記憶體佈局是連續的。
1. 記憶體分配
當宣告一個數組時,Go 語言會在記憶體中分配一塊連續的記憶體區域,用於儲存陣列的元素。陣列的長度在宣告時就已經確定,並且不能改變。
例如,宣告一個包含 5 個整數的陣列:
var arr [5]int
在這個例子中,Go 語言會在記憶體中分配一塊連續的記憶體區域,大小為 5 * sizeof(int)
位元組。假設 int
型別在當前平臺上佔用 4 個位元組,那麼這塊記憶體區域的大小就是 5 * 4 = 20
位元組。
2. 記憶體佈局
陣列的記憶體佈局是線性的,即陣列的每個元素在記憶體中是連續儲存的。陣列的第一個元素儲存在記憶體的起始位置,第二個元素緊隨其後,依此類推。
例如,對於陣列 arr := [5]int{1, 2, 3, 4, 5}
,其記憶體佈局如下:
記憶體地址: | arr[0] | arr[1] | arr[2] | arr[3] | arr[4] | 值: | 1 | 2 | 3 | 4 | 5 |
每個元素的記憶體地址可以透過陣列的基地址(即陣列的第一個元素的地址)加上元素的索引和元素型別的大小來計算。
3. 訪問陣列元素
由於陣列的記憶體佈局是連續的,訪問陣列元素非常高效。透過索引訪問陣列元素時,Go 語言會直接計算出該元素的記憶體地址,並從該地址讀取或寫入資料。
例如,訪問陣列 arr
的第三個元素:
value := arr[2]
Go 語言會計算出 arr[2]
的記憶體地址為 arr
的基地址加上 2 * sizeof(int)
位元組,然後從該地址讀取資料。
4. 陣列的傳遞
在 Go 語言中,陣列是值型別,這意味著當陣列作為引數傳遞給函式時,會進行一次完整的複製。如果陣列很大,這可能會導致效能問題。
例如:
func modifyArray(arr [5]int) { arr[0] = 100 } func main() { arr := [5]int{1, 2, 3, 4, 5} modifyArray(arr) fmt.Println(arr) // 輸出: [1 2 3 4 5] }
在這個例子中,modifyArray
函式接收的是 arr
的一個副本,因此修改副本不會影響原始陣列。
陣列的遍歷:
在 Go 語言中,遍歷陣列有多種方式,常用的方法包括使用 for
迴圈和 range
關鍵字。以下是幾種常見的遍歷陣列的方法:
1. 使用 for
迴圈和索引遍歷陣列
這是最基本的遍歷方式,透過索引訪問陣列的每個元素。
package main import "fmt" func main() { arr := [5]int{1, 2, 3, 4, 5} for i := 0; i < len(arr); i++ { fmt.Println(arr[i]) } }
2. 使用 range
關鍵字遍歷陣列
range
關鍵字可以方便地遍歷陣列,它會返回索引和對應的元素值。
package main import "fmt" func main() { arr := [5]int{1, 2, 3, 4, 5} for index, value := range arr { fmt.Printf("Index: %d, Value: %d\n", index, value) } }
3. 只使用 range
遍歷陣列的值
如果你只關心陣列的值而不關心索引,可以使用 _
忽略索引。
package main import "fmt" func main() { arr := [5]int{1, 2, 3, 4, 5} for _, value := range arr { fmt.Println(value) } }
4. 只使用 range
遍歷陣列的索引
如果你只關心陣列的索引而不關心值,可以只使用索引。
package main import "fmt" func main() { arr := [5]int{1, 2, 3, 4, 5} for index := range arr { fmt.Println(index) } }
5. 使用 for
迴圈和 range
遍歷多維陣列
對於多維陣列,可以巢狀使用 for
迴圈和 range
關鍵字。
package main import "fmt" func main() { arr := [2][3]int{{1, 2, 3}, {4, 5, 6}} for i := 0; i < len(arr); i++ { for j := 0; j < len(arr[i]); j++ { fmt.Printf("arr[%d][%d] = %d\n", i, j, arr[i][j]) } } // 使用 range 遍歷多維陣列 for i, row := range arr { for j, value := range row { fmt.Printf("arr[%d][%d] = %d\n", i, j, value) } } }