Data Type Slice - cruisechang/wiki-golang GitHub Wiki
Slice
Slice是Array的再包裝,Slice的底層是某個Array。反過來說,Slice就是對底層Array的連續片段的描述。
Slice是針對底層Array的某個連續片段操作,提供比Array更通用,方便,強大的介面。
建議:除非需要確定的長度,否則使用Slice而不使用Array。
Slice資料結構
ptr(*Elem),len(int),cap(int)
Slice本身包含三部分,prt+len+cap
prt is pointer to first element of base array
len是slice引用數目
cap是slice指向的底層array的那個元素,到最後一元素的數量
宣告及初始化
[]T
-
宣告不能指定長度,需要有類型
-
元素類型可以是任意一種golang有效的資料類型
-
Slice每個元素都有index,指定時不需要連續,Slice自己會補。但這樣不好。
因為Slice沒有長度規定,所以index不需從0開始,長度只需要在uint範圍內。只要不重複就可以了。
** Slice會自動補滿所有的index。例如0,9 , 會自動補中間的1-8,此時元素值是零值**
- 多個Slice的底層可共用同一個Array
a:=[]int{} //空slice
b:=[]interface{}{} //空slice第一個{}是interface,第二個是slice宣告
c:=[]struct{}{} //空slice,第一個{}是struct,第二個是slice宣告
d:=[]string{}
e:=[]string{"1","2","3"}
f:=[]string{5:"go",0:"java",3:"c"}
g:=[]string{0:"java",1:"",2:"",3:"c",4:"",5:"go"}
len 長度
意義是當前能使用的元素數目
len([]int{0:0,1:1,5:5})
//len=6
//slice自動填補3個int零值
var s []int
len(s) //len=0,未初始化的slice,長度為0
cap 容量
cap是ptr指向的那個元素到array的最後一個元素的數目,並非整個array的數目
意義是能訪問到的元素的最大數量
array:=[...]{"Go","Python","java","c","c++","c#"}
slice1:=array[:4]
cap(slice1) //6
slice2:=array[3:]
cap(slice2) //3
var s[]int
cap(s) //0,零值的slice,cap為0
Operation
擷取slice中的連續元素
ary:=[6]int{1,2,3,4,5,6}
s1:=ary[3:] //index 3 to end [4,5,6]
s2:=ary[:3] //index 0 to index 3 (不包括最後一個) [1,2,3]
s3:=ary[:] //all ary [1,2,3,4,5,6]
s4:=ary[1:4] //index 0 to index 4 (不包括最後一個) [2,3,4]
i:=s3[0] //get s3 index 0 element ,1
擴充當前slice可見範圍到最大
擴充到可見範圍最大,從pointer所指的元素到array最後一個元素
s1=s1[:cap(s1)] //[4,5,6]
s2=s2[:cap(s2)] //[1,2,3,4,5,6]
擷取並限制cap上限
ary:=[]int{1,2,3,4,5,6,7,8}
slice1:=ary[1:3:6] //cap上限為index 6
//cap(slice1)=5 不能擴充
slice2:=ary[:3:6] //begin index可以省略
slice2:=ary[0::6] //中間index不可以省略,會panic
append
append用來增加元素
append有可能更改base array,導致其他指向這個base array的slice內容也改變
當append的數量沒超過base array的容量,就直接修改base array
當append的數量超過base array的容量,會建立新base array
如果slice容量不夠,會自動擴充,
slice1:=[]string{"A","B"}
slice1=append(slice1,"R","E") //增加元素 "R","E" =["A","B","R","E"]
//append數量未超過base ary容量,base array被修改
ary:=[]int{1,2,3,4}
slice1:=ary[:3] //[1,2,3]
slice2:=ary[2:] //[3,4]
slice1=append(slice1,5)
//slice1 =[1,2,3,5]
//slice2= [3,5] 也改了
//append超過base ary容量,建立新base array
ary:=[]int{1,2,3,4}
slice1:=ary[:3] //[1,2,3]
slice2:=ary[2:] //[3,4]
slice1=append(slice1,5,6,7,8)
//slice1 =[1,2,3,5,6,7,8]
//slice2= [3,5] 沒改
copy
slice1:=[]int{1,2,3,4,5,6,7}
slice2:=[]int{10,11,12}
n:=copy(slice1,slice2) //n=3,以len小的為準
//slice1 len=7
//slice2 len=3