go基础6-切片

go的数组长度是不可变的   数组长度是数组内置的一个常量   无法对数组做增删操作

go语言提供了切片  支持动态增删操作

 

1 切片的定义

切片字面量中只有元素类型  没有长度

var  slice  []string    = []string{"a","b","c"}

 

 

 创建切片方法     三种   基于数组     基于切片      和直接创建

1 基于数组

months = [...]sring{"a","b","c","d"}//定义数组

//基于数组创建切片

n := months[1:2]  //2表示长度

m :=months[1:3]

c := months[2:3]//{"b","c"}

通过 array[start:end] 这样的方式基于数组生成切片

all := months[:]//

fisrtshalf   :=[:2]//前半部分     

half  := [2:]//包含从第二个元素开始

 

切片底层引用了一个数组  由三部分构成  --指针  长度  容量       容量是切片起始位置到底层数组结尾的位置       s :=a[3:6]    

获得容量函数    cap(s)

fmt.Println(cap(s))

fmt.Println(len(s))

 

2基于切片

 

b:=moths[:2]

c :=b[:1]    会受到数组容量限制   虽然是基于切片 但是本质还是基于数组

 

3 直接创建  make  

创建一个初始长度为5的整型切片

 a := make([]int,5)

创建一个初始长度为5 容量为10的切片  第三个参数定义容量

b := make([]int,5,10)

 

直接创建并初始化包含5个元素的切片   容量和长度都是5

c := []int{1,2,3,4,5}

使用直接创建方式创建切片时候  go底层还是会有一个匿名函数被创建 然后调用基于数组创建切片的方式返回切片   所以

切片都是基于数组 切片可以看做是操作数组的指针

 

二     遍历切片

for  i:=0;i<len(summer);i++{

  fmt.Println("summer[i] = ",summer[i])

}

 

for _,v := range summer{

  fmt.Println(v)

}

 

1 动态增加元素

切片支持动态增加元素     还可以在容量不足的情况下自动扩容  

元素的个数是切片的实际长度   而可分配的存储空间就是切片的容量

一个切片的容量初始值根据创建方式不同而不同

1对于基于数组和切片的切片而言  默认容量是切片起始索引到对应底层数组的结尾索引

2对应内置make 函数创建的而言  没有指定容量的情况下 默认容量和切片长度一致

cap  容量行数    len()  长度函数

var  old = make([]int,5,10)

fmt.Println(len(old))//5

fmt.Println(cap(old))//10

append()函数向切片追加

  old    目前是这样 的        {0,0,0,0,0}

$new  := append(old,1,2,3)

new     {0,0,0,0,0,1,2,3}

 

append的第二个参数是一个不定参数   可以添加多个   还可以切片

appendSlice :=[]int{1,2,3,4,5}

old := append(old,appendSlice...)  //注意末尾的。。。   不能省略

 

自动扩容 

如果追加的元素超过old的默认容量 则会自动扩容

new  := append(old,1,2,3,4,5,6,7)

自动扩容的容量会翻倍    比如原来的容量是10  扩容之后是20   当原切片长度大于或者等于1024时候 容量会以1.25倍扩容

 

内容复制

copy(z ,y)   右边复制到左边

如果2个切片不一样大   就会按照其中较小的那个切片的元素个数进行复制

   y := []int{1,2,3,4,5}

   z:= []int{6,7,8}

copy(z,y)  //1,2,3

copy(y,z) //6,7,8,4,5

 

动态删除元素

通过切片的切片实现

slice3 := []int{1,2,3,4,5,6,7,8,9,10}

//删除尾部的5个元素 

slice := slice3[:len(slice3)-5]

slice ;= slice3[5:]//删除头部的5个元素

还可以使用append    copy  实现切片元素的删除

slice10 := []int{1,2,3,4,5,6,7,8,9,10}

append(slice10[:0],slice3[3:]...)//删除开头的三个元素

 

数据共享的问题

type   slice  struct{

  array unsafe.Pointer//

       len    int

      cap   int

}

 

在结构体中使用指针存在不同实例订单数据共享问题  

slice1 := []int{1,2,3,4,5,6}

slice2 := slice[1:3]

slice2[1]  = 6;

slice   [1,2,6,4,5]

slice    [2,6]

slice2基于slice1创建的  他们的数组指针指向同一个数组  修改slice2会同步slice1    因为修改的是同一份内存数据

 

解决方案  

使用append函数   因为append函数执行扩容的时候会重新分配内存   如果初始容量没有进行扩容 使用append函数是无效的

 

posted @ 2021-04-09 14:51  fly_fly_fly#  阅读(34)  评论(0编辑  收藏  举报