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

  1. 宣告不能指定長度,需要有類型

  2. 元素類型可以是任意一種golang有效的資料類型

  3. Slice每個元素都有index,指定時不需要連續,Slice自己會補。但這樣不好。

因為Slice沒有長度規定,所以index不需從0開始,長度只需要在uint範圍內。只要不重複就可以了。

** Slice會自動補滿所有的index。例如0,9 , 會自動補中間的1-8,此時元素值是零值**

  1. 多個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