切片
切片有两种初始化方法,一种是字面量初始化,一种是make
不建议使用new
添加成员时,容量是2的指数递增的,2,4,8,16,32。而且是在长度要超过容量时,才增加容量。
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的错误。
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”
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的。
改为——
var b []mystruct2
a := make([]mystruct,len(b))
for index, item := range b{
a[index].mystring=item.mystring2
}
这样就可以解决了。
又如果,需要在循环里面筛选所需要的数据,则此时len(b)是b数组全部数据的长度。而切片给出初始大小后,得到的实际上是一个含有这个size数量切片类型的空元素。
因此没有被赋值的部分,仍然是“空”。
// 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做一些操作的时候(例如翻转)会出现一些空数据,取首位元素会取不到。
如
//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 的容量并不是可收缩的,用不上