<p align="right">2021年08月31日 13:54:49</p>
[TOC]
1. 數組:是同一數據類型的固定長度的序列
2. 數組定義:`var 變量名 [長度]類型`,例如`var a [5]int`,數組長度必須是常量,且是類型的組成部分,一旦定義長度不能改變。
3. 長度是數組類型的一部分,因此,`var a[5] int`和`var a[10]int`是不同的類型。
4. 數組可以通過下標進行訪問,下標是從0開始,最后一個元素下標是:len-1
```
for i := 0; i < len(a); i++ {
}
for index, v := range a {
}
```
5. 訪問越界,如果下標在數組合法范圍之外,則觸發訪問越界,會panic
6. 數組是值類型,賦值和傳參會復制整個數組,而不是指針。因此改變副本的值,不會改變本身的值。
7. 支持 `==`、`!=` 操作符,因為內存總是被初始化過的。
8. 指針數組 [n]*T,數組指針 *[n]T。
## 一維數組
```
package main
import (
"fmt"
)
var arr0 [5]int = [5]int{1, 2, 3}
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}
var str = [5]string{3: "hello world", 4: "tom"}
func main() {
a := [3]int{1, 2} // 未初始化元素值為 0。
b := [...]int{1, 2, 3, 4} // 通過初始化值確定數組長度。
c := [5]int{2: 100, 4: 200} // 使用引號初始化元素。
d := [...]struct {
name string
age uint8
}{
{"user1", 10}, // 可省略元素類型。
{"user2", 20}, // 別忘了最后一行的逗號。
}
fmt.Println(arr0, arr1, arr2, str)
fmt.Println(a, b, c, d)
}
```
## 多維數組
```
package main
import (
"fmt"
)
var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
func main() {
a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 緯度不能用 "..."。
fmt.Println(arr0, arr1)
fmt.Println(a, b)
}
```
## 值拷貝問題
值拷貝行為會造成性能問題,通常會建議使用 slice,或數組指針。
```
package main
import (
"fmt"
)
func test(x [2]int) { // 值類型會設置值拷貝造成性能問題
fmt.Printf("x: %p\n", &x)
x[1] = 1000
}
func main() {
a := [2]int{}
fmt.Printf("a: %p\n", &a)
test(a)
fmt.Println(a)
}
```
## 數組長度(元素數量)
```
package main
func main() {
a := [2]int{}
println(len(a), cap(a))
}
```
## 數組遍歷
```
package main
import (
"fmt"
)
func main() {
var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
for k1, v1 := range f {
for k2, v2 := range v1 {
fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
}
fmt.Println()
}
}
```
## 數組拷貝和傳值
```
package main
import (
"fmt"
)
func usingData(x [2]int) { // 值類型傳遞
fmt.Printf("x: %p\n", &x)
x[1] = 1
}
func usingPointer(x *[2]int) { // 引用類型傳遞
fmt.Printf("x: %p\n", x)
x[1] = 2
}
func main() {
a := [2]int{}
fmt.Printf("a: %p\n", &a)
usingData(a)
fmt.Println(a)
usingPointer(&a)
fmt.Println(a)
}
```
輸出結果
```
a: 0xc0000ac010
x: 0xc0000ac030
[0 0]
x: 0xc0000ac010
[0 2]
```