數組是具備相同惟一類型的一組已編號且長度固定的數據項序列。git
在 Go 語言中,數組的聲明方式爲 var identifier [len]type
。github
聲明時沒有指定數組的初始化值,所以全部的元素都會被自動初始化爲默認值 0。編程
// 聲明一個數組
var a1 [5]int
複製代碼
Go 語言中的數組是值類型,所以還能夠用 new
來建立:數組
var a2 = new([5]int)
複製代碼
new
返回類型的指針,所以 a1
與 a2
的區別在於:a1
的類型爲 [5]int
,a2
的類型爲 *[5]int
。bash
咱們經過在 {}
中填寫初始化值來初始化數組。ide
指明數組的長度 len
,而後在 {}
中填寫初始化值,這些值會按下標從小到大的順序分配。函數
初始化值的個數不容許超過長度 len
。當初始化值的個數小於 len
時,未被初始化的位置等於默認值 0。post
// 數組長度爲 5,初始化了前兩個數,未初始化的位是 0
b := [5]int{1, 2}
for index, val := range b {
fmt.Printf("下標 = %d, 值 = %d\n", 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, 值 = %d\n", index, val)
}
/* Output: 下標 = 0, 值 = 1 下標 = 1, 值 = 0 下標 = 2, 值 = 3 下標 = 3, 值 = 0 下標 = 4, 值 = 0 */
複製代碼
初始化時你也能夠不直接指明數組的長度,而是使用 [...]
代替。和指明數組長度時相同,此時也可使用順序填寫和指定索引兩種方式來初始化數組。ui
當使用 {a, b, c}
方式傳遞初始化值時,Go 語言將經過初始化元素的個數來肯定數組的長度:
// 經過傳遞初始化值肯定數組長度
// 傳遞了 5 個元素,數組長度爲 5
c := [...]int{1, 2, 3, 4, 5}
for index, val := range c {
fmt.Printf("下標 = %d, 值 = %d\n", 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, 值 = %d\n", 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,指針:%p\n", a, &a)
fmt.Printf("數組 b - 值:%v,指針:%p\n", 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,指針:%p\n", a, &a)
// 把數組 a 傳入函數
transmitA(a)
}
func transmitA(a [5]int) {
fmt.Printf("傳入函數的數組 a - 值:%v,指針:%p\n", 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
遍歷數組若是你以爲文章寫得不錯,請幫我兩個小忙:
你的鼓勵是我創做最大的動力,感謝你們!