Golang基础_04-切片slice

目录

@

简介

  • slice本身不是数组,它指向底层的数组
  • 是作为边长数组的替代方案,可以关联底层数组的局部或者全部
  • 为引用类型,类似指针
  • 可以直接创建或从底层数组获取生成,也可以用=直接从别的slice赋值
  • 使用len() 获取元素个数,cap()获取容量
  • 一般使用make()创建,make([]T,len,cap), 其中cap可以省略,此时和len的值相同,len表示存数的个数,cap表示容量
  • 如果len超过了cap,会重新分配内存cap,然后翻倍
  • 如果多个slice指向了同一个底层数组,其中一个的值改变会影响全部

    声明赋值和初始化

    方法一
func main(){
    a := [10]int{0,1,2,3,4,5,6,7,8,9}
    fmt.Println(a)
    //定义slice,[]里面不加任何东西
    var s1 []int
    s1 = a[5:10]
    //索引5到10,不包括10
    s2 := a[:5]
    //取下标从0到5,不包括5
    s3 := a[5:]
    s4 := a[5:len(a)]
    //从下标5开始,到最后一个元素,两式相同
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(s3)
    fmt.Println(s4)
}
/*
> Output:
command-line-arguments
[0 1 2 3 4 5 6 7 8 9]
[5 6 7 8 9]
[0 1 2 3 4]
[5 6 7 8 9]
[5 6 7 8 9]
*/

方法二

func main(){
    s1 := make([]int, 3, 10)
    fmt.Println(len(s1),cap(s1))
}
//3,10
  • slice的len就是当前的元素个数,cap是在对应数组中,开始位置到最后一个的长度
func main(){
    a := [9]byte{'a','b','c','d','e','f','g','h','i'}
    sa := a[2:5]
    fmt.Println("sa: ",len(sa),cap(sa),string(sa))
    sb := make([]byte,3,10)
    sb = sa[3:5]
    fmt.Println("sb: ",len(sb),cap(sb),string(sb))
}
/*
> Output:
command-line-arguments
sa:  3 7 cde
sb:  2 4 fg
*/

这里写图片描述

Reslice

  • reslice就是对一个slice进行slice
  • reslice时索引以被slice的切片为准
  • 索引不可以超过被slice的切片的cap()值
  • 索引越界不会导致底层数组的重新分配,而是引发错误

    append函数

  • 可以在slice尾部追加元素
  • 可以将一个slice追加在另一个slice尾部
  • 如果追加之后,最终长度未超过追加到slice的容量,就返回原始slice
  • 否则,就将重新分配数组(cap变成二倍)并拷贝原始数据
  • append增加了cap后,通过别的slice改变的元素,在这个slice里面不会改变,因为这个slice已经指向了别的新数组,meanwhile,改了这个slice也不回影响别的slice和原先的数组

func main(){
    a := make([]int,3,6)
    fmt.Printf("a: %p\n",a)
    s1 := append(a,1,2,3)
    fmt.Printf("s1: %v %p %d\n",s1,s1,cap(s1))
    fmt.Printf("a: %v %p %d\n",a,a,cap(a))
    s1 = append(s1,1,2,3)
    fmt.Printf("s1: %v %p %d\n",s1,s1,cap(s1))
}
/*
> Output:
command-line-arguments
a: 0xc042072030
s1: [0 0 0 1 2 3] 0xc042072030 6
a: [0 0 0] 0xc042072030 6
s1: [0 0 0 1 2 3 1 2 3] 0xc042046060 12
*/
  • append增加了cap后,通过别的slice改变的元素,在这个slice里面不会改变,因为这个slice已经指向了别的新数组,meanwhile,改了这个slice也不回影响别的slice和原先的数组
func main(){
    //全是slice
    a := []int{1,2,3,4,5}
    sa := a[1:5]
    sb := a[1:5]
    sb=append(sb,1,3,4,5,3,2,2,2)
    sb[2]=99
    fmt.Println(sb,sa)
}
/*
> Output:
command-line-arguments
[2 3 99 5 1 3 4 5 3 2 2 2] [2 3 4 5]
*/

copy函数

  • copy(a,b), 把b拷贝到a里面
  • 被拷贝操作的长度由短的哪一方决定
func main(){
    a := []int{1,2,3,4,5}
    b := []int{7,8,9}
    c := []int{11,22,333,44,55,66,77}
    copy(b,a)
    copy(c[2:4],a[1:3])
    fmt.Println(b,c)
}
/*
> Output:
command-line-arguments
[1 2 3] [11 22 2 3 55 66 77]
*/

猜你喜欢

转载自www.cnblogs.com/leafs99/p/golang_basic_04.html
今日推荐