這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
在Go語言中,數組長度在定義後就不可更改,在聲明時間長度度可以為一個常量或者一個常量運算式(常量運算式是指在編譯期即可計算結果的運算式)。數組的長度是該數群組類型的一個內建常量,可以用Go語言的內建函數len()來擷取。
數組的長度在定義後無法再次修改;數組是實值型別,每次傳遞都產生一份副本。
初看起來數組切片就像一個指向數組的指標,實際上它擁有自己的資料結構,而不僅僅是一個指標。數組切片的資料結構可以抽象為以下3個變數:
- 一個指向原生數組的指標
- 數組切片中元素的個數
- 數組切片已指派的儲存空間
從底層實現的角度看,數組切片實際上仍然使用數組來管理元素,基於數組,數組切片添加了一系列管理功能,可以隨時動態擴充存放空間,並且可以被隨意傳遞,而不會導致所管理的元素被複製。
下面用 reflect 包來反射出資料的類型。
package main
import(
"fmt"
"reflect"
)
func main(){
vs:=[]interface{}{
[]int{},// slice 切片
[]int{1,2,3},// slice 切片
[]int{1,2,3}[:],//切片再切還是切片
make([]int,3,10),//標準的slice 定義方式
[3]int{1,2,3},//array 數組,確定數組長度
[...]int{1,2,3},//array 數組,由編譯器自動計算數組長度。
}
for i,v:=range vs{
rv:=reflect.ValueOf(v)//進入瘋狂的reflect世界
fmt.Println(i,rv.Kind())
}
}
上述程式執行結果:
0 slice
1 slice
2 slice
3 slice
4 array
5 array
注意slice和數組在聲明時的區別:聲明數組時,方括弧內寫明了數組的長度或使用...自動計算長度,而聲明slice時,方括弧內沒有任何字元。
數組切片的擴容:
ww:=make([]int,3,5)
ww[0]=23
ww[1]=23
ww[2]=23
//ww[3]=34// 這樣賦值會報錯誤 panic: runtime error: index out of range 超過了切片的大小
fmt.Println(cap(ww))
ww=append(ww,2,4,34)//需要用 append 給賦值, append 在儲存空間不足時,會自動增加儲存空間
fmt.Println(cap(ww))
fmt.Println(ww)
註:append函數會改變slice所引用的數組的內容,從而影響到引用同一數組的其它slice。 但當slice中沒有剩餘空間(即(cap-len) == 0)時,此時將動態分配新的數組空間。返回的slice數組指標將指向這個空間,而原數組的內容將保持不變;其它引用此數組的slice則不受影響。
參考:
數組(Array)和切片(Slice)
http://my.oschina.net/lxpan/blog/87432
Golang Go語言Array數組與Slice切片的不同
http://kejibo.com/golang-slice-array-reflect/
2.2 Go基礎
https://github.com/astaxie/build-web-application-with-golang/blob/master/02.2.md