文章目錄
-
- 08 Go語言數組
-
- 8.1 數組的聲明和初始化
-
- 數組的聲明
- 數組的初始化
- 8.2 數組在記憶體中的結構
- 8.3 使用數組
-
- 通路數組元素
- 修改元素值
- 周遊數組
- 相同類型的數組互相指派
- 向函數傳遞數組
- 向函數傳遞數組的指針
- 數組使用注意事項
08 Go語言數組
數組是由相同資料類型的元素組成的一組已編号且長度固定的資料項序列。
數組的特點:
- 每個元素具有相同的資料類型
- 每個元素在數組中有唯一的編号,稱作數組下标,下标從0開始
- 數組的長度是固定的,而且該長度必須是一個常量表達式
由于數組的長度是固定的,而切片類型的長度可以動态變化,是以在Go裡面很少直接使用數組而是使用切片。但是為了更好的了解切片,我們必須先了解數組。
8.1 數組的聲明和初始化
數組的聲明
Go語言聲明數組時需要指明元素類型和元素個數,文法如下:
var variable_name [SIZE]variable_type
例如:
// 定義一個長度為10的int數組
var values [10]int
數組的初始化
以上聲明的數組雖然沒有明确的初始化,但編譯器會使用零值對數組每個元素初始化。int類型的零值是數字0,是以上面的數組每個元素的值都是數字0。
當然,也可以在聲明數組的時候對其明确的初始化,如下:
// 需注意:初始化時,{}中的元素個數不能超過[]中的數字。
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
也可以省略[]中的數字,Go語言會根據元素的個數自動設定數組的大小,如下:
// 本例子與上面的例子時一樣的,雖然沒有明确設定數組大小
var values = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
如果我們隻想給數組的部分元素初始化,其他元素初始為零值我們可以用下面的方式初始化:
// 隻給數組下标為0的元素指派為5,下标為4的元素指派為5,其他下标的元素初始化為零值
var values = [10]int{0:2, 4:5}
8.2 數組在記憶體中的結構
上面代碼所定義的數組在記憶體中的結構如下:

由上面的圖我們可知:
- 數組的起始位址就是它第一個元素的位址,即:&values == &values[0]。
- 數組每個元素占用記憶體大小是相等的,對于int數組,每個元素都占8位元組(在64位的系統上,int類型是8個位元組)。
- 數組的元素在記憶體中是連續配置設定的,對于int數組,每個元素的位址比前一個元素位址大8位元組,這8位元組正好是單個數組元素的大小。
8.3 使用數組
通路數組元素
數組元素可以通過索引(位置)來讀取。如下:
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(values[0])
fmt.Println(values[1])
fmt.Println(values[2])
i := 3
fmt.Println(values[i])
i++
fmt.Println(values[i])
通路數組元素時不可以越界,否則發生當機異常:
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
v := values[10] // 數組下标最大值時9,使用下标10通路數組元素發生越界
修改元素值
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
values[0] = 100
values[1] = 200
values[2] += 300
fmt.Println(values)
周遊數組
使用索引周遊:
for i := 0; i < len(values); i++ { // len()傳回數組元素個數
fmt.Println(values[i])
}
使用for-range周遊:
for i, v := range values {
fmt.Println("索引是:", i, "值是:", v)
}
相同類型的數組互相指派
什麼是相同類型的數組?Go語言規定,長度一樣且元素類型一樣的數組就是相同類型的數組。
values := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var values2 [10]int = values // 可以
var values3 [8]int = values // 不可以
由于數組屬于值類型,是以數組指派的時候會拷貝整個數組。
向函數傳遞數組
如果你希望向函數傳遞數組,那麼在定義函數的時候需要聲明形參是數組:
func myFunction(param [10]int) {
// ...
}
調用該函數時,傳入一個數組,由于數組是值類型,是以給myFunction的數組是原來數組的拷貝,對形參數組的修改不會改變原來的數組。例如:
func main() {
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
myFunction(values)
fmt.Println(values) // 輸出 [1 2 3 4 5 6 7 8 9 10]
}
func myFunction(param [10]int) {
param[0] = 100
}
向函數傳遞數組的指針
如果想向函數傳遞數組的指針,那麼在定義函數的時候需要聲明形參是數組指針類型:
func myFunction(param *[10]int) {
// ...
}
對于這種方式,由于向函數傳遞的是數組的位址,是以在函數内部對數組内容修改後,修改的就是原數組。例如:
func main() {
var values = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
myFunction(&values)
fmt.Println(values) // 輸出 [100 2 3 4 5 6 7 8 9 10]
}
func myFunction(param *[10]int) {
param[0] = 100 // Go語言會自動對指針解引用,本語句等價于 (*param)[0] = 1000
}
數組使用注意事項
- 數組的元素都是同一類型的
- 數組的長度是固定的,定義完數組之後,數組的長度不能動态變化
- 數組聲明時,如果未明确初始化,那麼會把各元素初始化為元素類型對應的零值
- 數組下标從0開始
- 不可以越界通路數組,否則發生當機異常
- 數組屬于值類型,預設情況下是值傳遞,是以會進行值拷貝
- 如果想在其他函數中修改原來的數組,可以使用傳數組指針的方式
- 類型相同但長度不同的數組,不是同一類型的數組,不可以互相指派
[email protected] , [email protected]