go append函數以及寫入

切片

切片有兩種初始化方法,一種是字面量初始化,一種是make
不建議使用new
添加成員時,容量是2的指數遞增的,2,4,8,16,32。並且是在長度要超過容量時,才增長容量。golang

append函數

append(type,len,cap)
該函數第一個參數是類型,第二個參數是分配的空間,第三個參數是預留分配空間
a:=make([]int, 5, 10)
a[4]// 正確
a[5]//報錯

這是由於cap預留的空間須要從新切片纔可使用,例如動態追加的時候從新分配空間之類。
也能夠手動分配數組

func main(){
    a := make([]int, 10, 20)
    fmt.Println(a)
    b := a[:cap(a)]
    fmt.Println(b)
}
//[0 0 0 0 0 0 0 0 0 0]
//[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

是將一個元素追加到數組的最後,他是go的內置函數。
當咱們用append追加元素到切片時,若是容量不夠,go就會建立一個新的切片變量
所以append是動態增長的。不用擔憂 出現 index out of range的錯誤。app

var s []string 
s= append(s ,"last")

append比較適合用字面量初始的切片。
由於make傳入初始大小後,咱們獲得的其實是一個含有這個size數量切片類型的空元素。此時使用append會在空元素以後再追加。函數

func main(){
    var s=make([]string,10);
    s=append(s,"last");
    print(s)
}
// ["0","0","0","0","0","0","0","0","0","0","last"]

若是要繼續使用make來初始化的話,那麼須要用到第三個參數,「cap」code

func main(){
    var s=make([]string,0,10);
    s=append(s,"last");
    print(s)
}
// ["last"]

append侷限性

但有其侷限性,例如不能用在對象

type mystruct{
mystring string 
}
type mystruct2{
mystring2 string 
}
var a []mystruct
var b []mystruct2
for _, item := range b{
    b=append(a.mystring,item.mystring2)
}

而想要能夠給對象數組的子屬性 ,按照數組的原定順序添加(所以也不能直接把a變成map遍歷了,除非按照某種順序從新排序),想到的一個方法是使用直接賦值表達式排序

for index, item := range b{
   a[index].mystring=item.mystring2
}

可是這樣會報錯,提示index out of range .由於a聲明是默認初始化長度爲0的。
改成——get

var b []mystruct2
a := make([]mystruct,len(b))
for index, item := range b{
   a[index].mystring=item.mystring2
}

這樣就能夠解決了。
又若是,須要在循環裏面篩選所須要的數據,則此時len(b)是b數組所有數據的長度。而切片給出初始大小後,獲得的其實是一個含有這個size數量切片類型的空元素。
所以沒有被賦值的部分,仍然是「空」。string

// a=[{"A"},{"B"},{"C"},{"D"}]
var b []mystruct2
a := make([]mystruct,len(b))
for index, item := range b{
if(index/2!=0){//奇數index
   a[index].mystring=item.mystring2
   }
}
//a=[{"A"},{},{"C"},{}]

則在對a作一些操做的時候(例如翻轉)會出現一些空數據,取首位元素會取不到。
it

//a=[{"A"},{},{"C"},{}]
func InvertedOrder(arr []mystruct)([]mystruc){
    for from , to := 0 , len(arr) -1 ; from < to ; from , to = from + 1, to -1{
        arr[from] , arr[to] = arr[to] , arr[from]
    }
    return arr
}
a_invert := InvertedOrder(a)
//a=[{},{"C"},{},{"A"}]

一個比較low的方法是計數,而後從新切片

var count
for index, item := range b{
if(index/2!=0){//奇數index
    count++
   a[count-1].mystring=item.mystring2
   }
}
a=a[:count]

沒有想到其餘比較好的方法,初始化slice 的容量並非可收縮的,用不上

參考

https://studygolang.com/artic...

相關文章
相關標籤/搜索