認識 Go 語言中的陣列
作者:
程式設計拯救世界(ID: CodeWarrior_):專注於程式設計基礎與服務端研發。
陣列是具有相同唯一型別的一組已編號且長度固定的資料項序列。
宣告方式
在 Go 語言中,陣列的宣告方式為 var identifier [len]type
。
宣告時沒有指定陣列的初始化值,因此所有的元素都會被自動初始化為預設值 0。
// 宣告一個陣列
var a1 [5]int
Go 語言中的陣列是值型別,因此還可以用 new
來建立:
var a2 = new([5]int)
new
返回型別的指標,因此 a1
與 a2
的區別在於:a1
的型別為 [5]int
,a2
的型別為 *[5]int
。
初始化方法
我們透過在 {}
中填寫初始化值來初始化陣列。
指明陣列長度
指明陣列的長度 len
,然後在 {}
中填寫初始化值,這些值會按下標從小到大的順序分配。
初始化值的個數不允許超過長度 len
。當初始化值的個數小於 len
時,未被初始化的位置等於預設值 0。
// 陣列長度為 5,初始化了前兩個數,未初始化的位是 0
b := [5]int{1, 2}
for index, val := range b {
fmt.Printf("下標 = %d, 值 = %dn", index, val)
}
/* Output:
下標 = 0, 值 = 1
下標 = 1, 值 = 2
下標 = 2, 值 = 0
下標 = 3, 值 = 0
下標 = 4, 值 = 0
*/
也可以使用 {index1: a, index2: b}
的方式初始化陣列,指明陣列的索引和對應的下標值,未指明的下標所在位置的值等於預設值 0:
// 透過陣列索引初始化
// d[0] = 1, d[2] = 3,其他位置等於 0
d := [5]int{0: 1, 2: 3}
for index, val := range d {
fmt.Printf("下標 = %d, 值 = %dn", index, val)
}
/* Output:
下標 = 0, 值 = 1
下標 = 1, 值 = 0
下標 = 2, 值 = 3
下標 = 3, 值 = 0
下標 = 4, 值 = 0
*/
暗示陣列長度
初始化時你也可以不直接指明陣列的長度,而是使用 [...]
代替。和指明陣列長度時相同,此時也可以使用順序填寫和指定索引兩種方式來初始化陣列。
當使用 {a, b, c}
方式傳遞初始化值時,Go 語言將透過初始化元素的個數來確定陣列的長度:
// 透過傳遞初始化值確定陣列長度
// 傳遞了 5 個元素,陣列長度為 5
c := [...]int{1, 2, 3, 4, 5}
for index, val := range c {
fmt.Printf("下標 = %d, 值 = %dn", index, val)
}
/* Output:
下標 = 0, 值 = 1
下標 = 1, 值 = 2
下標 = 2, 值 = 3
下標 = 3, 值 = 4
下標 = 4, 值 = 5
*/
若透過指明陣列的索引和對應的值來初始化陣列,此時陣列的長度就等於 最大索引數 + 1
:
// 最大索引是 9,所以陣列的長度為 10
e := [...]int{9: 10}
for index, val := range e {
fmt.Printf("下標 = %d, 值 = %dn", index, val)
}
/* Output:
下標 = 0, 值 = 0
下標 = 1, 值 = 0
下標 = 2, 值 = 0
下標 = 3, 值 = 0
下標 = 4, 值 = 0
下標 = 5, 值 = 0
下標 = 6, 值 = 0
下標 = 7, 值 = 0
下標 = 8, 值 = 0
下標 = 9, 值 = 10
*/
陣列的遍歷
在 Go 語言中使用 for ... range
遍歷陣列:
// i 是陣列索引
for i, _ := range arr1 {
// do something
}
陣列是值型別
和 C/C++ 不同,Go 語言的陣列是值型別的。這樣一來,賦值和傳參都會複製整個陣列,而不是指標。
我們初始化一個陣列 a
,並把它賦值給陣列 b
,然後列印兩者的值與指標:
a := [5]int{1, 2, 3, 4, 5}
b := a
fmt.Printf("陣列 a - 值:%v,指標:%pn", a, &a)
fmt.Printf("陣列 b - 值:%v,指標:%pn", b, &b)
/* Output:
陣列 a - 值:[1 2 3 4 5],指標:0xc00001e0f0
陣列 b - 值:[1 2 3 4 5],指標:0xc00001e120
*/
可以看到,兩者的值是相同的,但是記憶體地址卻不同,說明在賦值的過程中複製了整個陣列。
我們再來看一下傳參的例子。
定義一個函式 transmitA
,把剛才我們初始化的陣列 a
傳入:
func main() {
a := [5]int{1, 2, 3, 4, 5}
fmt.Printf("陣列 a - 值:%v,指標:%pn", a, &a)
// 把陣列 a 傳入函式
transmitA(a)
}
func transmitA(a [5]int) {
fmt.Printf("傳入函式的陣列 a - 值:%v,指標:%pn", a, &a)
}
/* Output:
陣列 a - 值:[1 2 3 4 5],指標:0xc00001e0f0
傳入函式的陣列 a - 值:[1 2 3 4 5],指標:0xc00001e150
*/
從輸出可以看出,兩者的值依然相同,記憶體地址卻是不同的。這說明在傳參時陣列也被複制了。
陣列指標與指標陣列
陣列指標與指標陣列聽起來似乎有點拗口,那麼來展開說明一下:
- 陣列指標:(指向)陣列(的)指標
- 指標陣列:(裝滿了)指標(的)陣列
也就是說,陣列指標是個指標,它指向一個陣列;而指標陣列是個陣列,它裡面裝滿了指標。
陣列指標
宣告一個陣列 a
,然後將它的地址賦值給 arrayPointer
。這樣一來,arrayPointer
就是一個指向陣列 a
的指標,即陣列指標,它的型別為 *[5]int
。
a := [5]int{1, 2, 3, 4, 5}
// 把陣列 a 的地址賦值給 arrayPointer
// arrayPointer 是指向陣列的指標,型別為 *[5]int
arrayPointer := &a
fmt.Println(arrayPointer)
/* Output:
&[1 2 3 4 5]
*/
指標陣列
初始化陣列 pointerArray
,傳入的初始化值為整型 m
與 n
的記憶體地址(&m
和 &n
),那麼 pointerArray
就是一個裝著 int
型別指標的陣列,即指標陣列,它的型別為 [2]*int
。
m := 1
n := 2
// 初始化 pointerArray,傳入 m 與 n 的地址
// pointerArray 包含了整型地址,是一個裝著指標的陣列
pointerArray := [2]*int{&m, &n}
fmt.Println(pointerArray)
/* Output:
[0xc0000aa000 0xc0000aa008]
*/
總結
- 陣列的長度是固定的,初始化時需要「明示」或「暗示」陣列的長度
-
陣列的長度是陣列型別的組成部分,
[2]int
與[100]int
是不同型別的陣列 - 使用
for ... range
遍歷陣列 - 在 Go 語言中,陣列是值型別,賦值和傳遞引數都會發生陣列的複製
- 陣列指標是一個指標,它指向了一個陣列
- 指標陣列是一個陣列,它裡面裝著指標
參考資料
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/810/viewspace-2824278/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 聊聊Go語言中的陣列與切片Go陣列
- go語言中遍歷陣列的方法有哪些Go陣列
- 簡單分析Go語言中陣列的這些細節Go陣列
- c語言中三維陣列C語言陣列
- c語言中陣列的三種型別C語言陣列型別
- go 語言陣列Go陣列
- go 語言中預設的型別識別Go型別
- JavaScript中對陣列和陣列API的認識JavaScript陣列API
- c語言中計算陣列長度的方法C語言陣列
- c語言中陣列的宣告與初始化C語言陣列
- Go 語言中的方法Go
- C語言中陣列溢位是什麼C語言陣列
- Go 語言中的 collect 使用Go
- Go 語言中的 切片 --sliceGo
- Go 語言中的外掛Go
- c語言中二維陣列的生成及應用C語言陣列
- go語言之陣列與切片Go陣列
- js二維陣列新認識JS陣列
- GO 語言中的物件導向Go物件
- Go語言中的併發模式Go模式
- c語言中實現4行3列矩陣和3行4列矩陣的運算C語言矩陣
- C語言中陣列首地址和陣列第一個元素的地址有什麼區別C語言陣列
- C語言中“陣列名”和“&陣列名”C語言陣列
- 詳解資料結構中的“陣列”與程式語言中的“陣列”的區別和聯絡資料結構陣列
- Julia 語言中的生成器表示式與陣列推導式陣列
- Go 語言中使用 ETCDGo
- Go語言中的變數作用域Go變數
- Go語言中的單元測試Go
- go語言學習-陣列-切片-mapGo陣列
- Go語言之陣列快速入門篇Go陣列
- Go中的陣列Go陣列
- c語言中陣列的宣告喝初始化的區別和聯絡C語言陣列
- Go 語言中的兩種 slice 表示式Go
- Go語言中defer的一些坑Go
- 9.Go語言中的流程控制Go
- Go 語言中的格式化輸出Go
- 詳細解讀go語言中的chnanelGoNaN
- Go語言中時間輪的實現Go