原文:CalliCoder — Working with Arrays in Golang
陣列是固定長度的相同型別元素的集合。陣列的元素按順序儲存,並且可以使用它們的 index
來存取。
在 Golang 中宣告陣列
你可以像這樣宣告一個長度為 n
且型別為 T
的陣列:
var a[n]T
舉例來說,以下是如何宣告一個長度為 10 的整數陣列:
// An array of 10 integers
var a[10]int
現在,讓我們看一個完整範例:
package main
import "fmt"
func main() {
var x [5]int // An array of 5 integers
fmt.Println(x)
var y [8]string // An array of 8 strings
fmt.Println(y)
var z [3]complex128 // An array of 3 complex numbers
fmt.Println(z)
}
# Output
[0 0 0 0 0]
[ ]
[(0+0i) (0+0i) (0+0i)]
預設情況下,所有陣列元素皆使用與陣列型別一致的零值初始化。
舉例來說,如果我們宣告一個整數陣列,則所有元素都將以 0
初始化。如果我們宣告一個字串陣列,則所有元素都將以空字串 ""
初始化,依此類推。
透過索引存取陣列元素
陣列的元素按順序儲存,可以透過它們的 index
存取。index
從零開始,結束於 length - 1
。
package main
import "fmt"
func main() {
var x [5]int // An array of 5 integers
x[0] = 100
x[1] = 101
x[3] = 103
x[4] = 105
fmt.Printf("x[0] = %d, x[1] = %d, x[2] = %d\n", x[0], x[1], x[2])
fmt.Println("x = ", x)
}
# Output
x[0] = 100, x[1] = 101, x[2] = 0
x = [100 101 0 103 105]
在上面的範例中,由於我們沒有分派 x[2]
任何值,因此它的值為 0
(整數的零值)。
使用陣列定數初始化陣列
你可以像這樣同時宣告並初始化陣列:
// Declaring and initializing an array at the same time
var a = [5]int{2, 4, 6, 8, 10}
上面表達式右側的陳述式稱為陣列定數。
注意,我們不需要像 var a [5]int
中那樣指定變數 a
的型別,因為編譯器可以從右側的表達式自動推斷型別。
你也可以使用 Golang 的簡短變數宣告來宣告和初始化陣列。上面的陣列宣告也可以在任何函數內撰寫如下:
// Short hand declaration
a := [5]int{2, 4, 6, 8, 10}
這是一個完整範例:
package main
import "fmt"
func main() {
// Declaring and initializing an array at the same time
var a = [5]int{2, 4, 6, 8, 10}
fmt.Println(a)
// Short declaration for declaring and initializing an array
b := [5]int{2, 4, 6, 8, 10}
fmt.Println(b)
// You don't need to initialize all the elements of the array.
// The un-initialized elements will be assigned the zero value of the corresponding array type
c := [5]int{2}
fmt.Println(c)
}
# Output
[2 4 6 8 10]
[2 4 6 8 10]
[2 0 0 0 0]
讓 Go 編譯器推斷陣列的長度
你還可以從陣列的初始化表達式中省略長度宣告,並讓編譯器為你計算元素的數量:
package main
import "fmt"
func main() {
// Letting Go compiler infer the length of the array
a := [...]int{3, 5, 7, 9, 11, 13, 17}
fmt.Println(a)
}
# Output
[3 5 7 9 11 13 17]
探索有關 Golang 陣列的更多資訊
- 陣列的長度是其型別的一部分
陣列的長度是其型別的一部分。因此陣列 a[5]int
和 a[10]int
是完全不同的型別,且你不能將一個分派給另一個。
也就是說你無法調整陣列長度,因為調整陣列的長度將意味著更改其型別,而你無法在 Golang 中更改變數的型別。
package main
func main() {
var a = [5]int{3, 5, 7, 9, 11}
var b [10]int = a // Error, a and b are distinct types
}
- Golang 中的陣列是數值型別
Golang 中的陣列是數值型別,不像其他語言,如 C、C++ 和 Java 的陣列是參考型別。
這意味著當你將陣列賦值給新變數或將陣列傳遞給函數時,將複製整個陣列。因此,如果你對此複製的陣列進行任何更改,原始陣列將不會受到影響且保持不變。
這有一個範例:
package main
import "fmt"
func main() {
a1 := [5]string{"English", "Japanese", "Spanish", "French", "Hindi"}
a2 := a1 // A copy of the array `a1` is assigned to `a2`
a2[1] = "German"
fmt.Println("a1 = ", a1) // The array `a1` remains unchanged
fmt.Println("a2 = ", a2)
}
# Output
a1 = [English Japanese Spanish French Hindi]
a2 = [English German Spanish French Hindi]
在 Golang 中迭代陣列
你可以像這樣使用 for
迴圈迭代陣列:
package main
import "fmt"
func main() {
names := [3]string{"Mark Zuckerberg", "Bill Gates", "Larry Page"}
for i := 0; i < len(names); i++ {
fmt.Println(names[i])
}
}
# Output
Mark Zuckerberg
Bill Gates
Larry Page
上面的範例中,len()
函數用於找出陣列的長度。
讓我們來看另一個範例。在下面的範例中,我們透過迭代陣列,將元素逐一加到變數 sum
中,找出陣列所有元素的總和:
package main
import "fmt"
func main() {
a := [4]float64{3.5, 7.2, 4.8, 9.5}
sum := float64(0)
for i := 0; i < len(a); i++ {
sum = sum + a[i]
}
fmt.Printf("Sum of all the elements in array %v = %f\n", a, sum)
}
# Output
Sum of all the elements in array [3.5 7.2 4.8 9.5] = 25.000000
使用 range
迭代陣列
Golang 使用 range
運算子提供了一種更強大的 for
迴圈形式。以下是如何將 range
運算子與 for
迴圈一起使用來迭代陣列:
package main
import "fmt"
func main() {
daysOfWeek := [7]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
for index, value := range daysOfWeek {
fmt.Printf("Day %d of week = %s\n", index, value)
}
}
# Output
Day 0 of week = Mon
Day 1 of week = Tue
Day 2 of week = Wed
Day 3 of week = Thu
Day 4 of week = Fri
Day 5 of week = Sat
Day 6 of week = Sun
現在,讓我們使用 range
形式的 for
迴圈來撰寫一個與普通 for
迴圈相同的 sum
範例:
package main
import "fmt"
func main() {
a := [4]float64{3.5, 7.2, 4.8, 9.5}
sum := float64(0)
for index, value := range a {
sum = sum + value
}
fmt.Printf("Sum of all the elements in array %v = %f", a, sum)
}
當你執行上面的程式時,它會產生以下錯誤:
# Output
./array_iteration_range.go:9:13: index declared and not used
Go 編譯器不允許建立從未使用過的變數。你可以透過使用 _
(底線) 代替 index
來解決此問題:
package main
import "fmt"
func main() {
a := [4]float64{3.5, 7.2, 4.8, 9.5}
sum := float64(0)
for _, value := range a {
sum = sum + value
}
fmt.Printf("Sum of all the elements in array %v = %f", a, sum)
}
底線(_
)用於告訴編譯器我們不需要此變數。上面的程式現在可以成功執行並輸出陣列的總和:
# Output
Sum of all the elements in array [3.5 7.2 4.8 9.5] = 25.000000
Golang 中的多維陣列
到目前為止,我們在本文中建立的所有陣列都是一維的。你也可以在 Golang 中建立多維陣列。
以下範例示範了如何建立多維陣列:
package main
import "fmt"
func main() {
a := [2][2]int{
{3, 5},
{7, 9}, // This trailing comma is mandatory
}
fmt.Println(a)
// Just like 1D arrays, you don't need to initialize all the elements in a multi-dimensional array.
// Un-initialized array elements will be assigned the zero value of the array type.
b := [3][4]float64{
{1, 3},
{4.5, -3, 7.4, 2},
{6, 2, 11},
}
fmt.Println(b)
}
# Output
[[3 5] [7 9]]
[[1 3 0 0] [4.5 -3 7.4 2] [6 2 11 0]]
結論
陣列很有用,但由於其固定長度而造成的限制而有些不靈活。這就是為什麼 Go 提供了另一個名為 Slice 的資料結構,該資料結構建構在陣列之上,並提供了我們所需的所有靈活性。在下一篇文章中,我們將學習 Slice。