數組 Go的數組和其它語言基本上一樣,是長度固定的特定類型元素組成的序列,這基本上是所有語言數組的特性。和其它語言相比差異主要在聲明和初始化的寫法上,下麵是簡單聲明一個數組: var a [5]int fmt.Println(a[0]) fmt.Println(fmt.Println(a[len(a ...
目錄
數組
Go
的數組和其它語言基本上一樣,是長度固定的特定類型元素組成的序列,這基本上是所有語言數組的特性。和其它語言相比差異主要在聲明和初始化的寫法上,下麵是簡單聲明一個數組:
var a [5]int
fmt.Println(a[0])
fmt.Println(fmt.Println(a[len(a)-1]))
上面的a
是一個長度為5
的整數數組,如果沒有給定初始值它裡面的元素預設值是0
。Go
數組的下標是從0開始的,len
函數返回數組中元素的個數。我們可以在聲明數組的時候初始化它的值:
var m [3]int = [3]int{1, 2, 3}
var n [3]int = [3]int{2, 3}
這裡的m
和n
都是長度為3
的數組,m
對應的值是1, 2, 3
而由於n
初始化的時候只有2
個值,因此它裡面的值是2, 3, 0
。
如果採用簡單聲明:=
的方式聲明一個數組,可以指定數組的大小,也可以不指定大小這時它會根據初始化值的個數來確定:
a := [10]int{} //元素都為0
b := [...]int{1, 2} //長度為2
Go
也可以直接指定一個索引和值,來初始化,如果聲明的時候長度不指定,那最大的索引加1
就是數組的長度:
a := [10]int{1:2} // 長度10,a[1] = 2 其它為0
b := [...]int{1:2, 10:1} //長度11,a[1] = 2 a[10] = 1其它為0
數組a
長度聲明是10
,只給了索引1
的值為2
,其餘都為0
。數組b
聲明的時候索引1
為2
,10
為1
,它的長度是11
修改數組中某個索引的值方式和其它語言一樣:
a := [10]int{}
a[0] = 10
數組的類型是由元素的類型和長度共同決定的,[3]int
和[4]int
是兩種不同的數組類型。因此:
a := [3]int{1, 2, 3}
a = [4]int{1, 2, 3, 4}
編譯的時候會報錯,而:
a := [3]int{1, 2, 3}
a = [3]int{4, 5, 6}
是正確的
Slice
上面說的數組長度是固定,使用的時候不是很靈活,slice
的長度是可變,簡單聲明一個未初始化的slice
var a []int
print(len(a))
print(cap(a))
slice
也可以利用len
返回它的長度,剛纔聲明的slice
長度為0
。除了長度slice
還有一個容量cap
的概念,用cap
可以返回它的容量。長度不能超過它的容量。slice的聲明也可以用make
,用make
聲明可以指定容量和可以不指定容量,這時容量和長度一致:
a := make([]int, 10) //長度為10,容量為10
a := make([]int, 10, 12) //長度為10 容量為12
slice
可以進行切片操作slice[i:j]
,創建一個新的slice
,新的slice
範圍是原來slice
下標i
到j-1
,也可以不指定下標slice[:j]
則是預設從0
到j-1
,同理如果slice[i:]
就是從i
到最後一個元素,下麵是一個簡單的例子:
a := []int {1, 2, 3, 4, 5}
b = a[1:2]
c = a[:2]
d = a[1:]
需要註意的是切片操作slice[i:j]
,j
可以大於slice
的長度,只要它小於容量
剛纔一直講到容量,那它到底有什麼實際意義呢?開始slice
的時候說過它長度是可變的,哪怎麼改變了?通過append
就可以對slice
追加元素,這時容量就有作用了,如果append的時候當前長度小於容量,那slice
不會擴大容量,也不會申請新的空間,而是在原來的基礎上把長度加1
就行了,如果容量等於長度,則會擴容,擴容會申請新的空間。
package main
func main() {
a := make([]int, 10, 11)
a = append(a, 1)
println(len(a), cap(a)) // 11 11
a = append(a, 1)
println(len(a), cap(a)) // 12 12
}