zoukankan      html  css  js  c++  java
  • Go的切片

    切片

    切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。

    因此切片的类型是引用类型。

    一、切片的创建

    1、先创建数组,再引用

    // 先创建一个数组
    var lis [10]int= [10]int{1,2,3,4,5,6,7,8,9,10}
    // 创建切片
    var sli = lis[:]  // 从头到尾全切
    fmt.Println(sli)  // [1 2 3 4 5 6 7 8 9 10]
    fmt.Printf("%T",sli)  // []int  
    // []内没有数字就是切片,有就是数组
    

    2、直接创建切片

    var a []int=[]int{1,2,3,4,5}  //切片初始化,类似于数组初始化
    

    二、切片的修改

    因为切片是引用类型,它是对数组的引用。所以切片的修改会影响原来的数组,数组的修改也会影响切片。

    var lis [10]int= [10]int{1,2,3,4,5,6,7,8,9,10}
    
    var b []int = lis[5:9]  // 索引取值,左开右闭
    b[0]=999
    lis[6]=888
    fmt.Println(b)
    fmt.Println(lis)
    
    [999 888 8 9]
    [1 2 3 4 5 999 888 8 9 10]
    

    三、切片的长度和容量

    len() :长度,现在有多少值
    cap() :容量,总共能放多少值,为引用的数组长度-切片首位索引

    var lis [10]int= [10]int{1,2,3,4,5,6,7,8,9,10}
    
    var b []int = lis[5:9]  
    
    fmt.Println(len(b))  // 4
    fmt.Println(cap(b))  // 5  //(10-5)
    

    四、使用make创建切片

    用函数make([]T,len,cap)来创建切片类型的变量,就不用先创建数组了。

    函数参数分别为:类型,长度和容量。

    容量是可选参数, 默认值为切片长度。

    make 函数原理为创建一个数组,并返回引用该数组的切片。

    var sli []int=make([]int,3,4)
    fmt.Println(len(sli))  // 3
    fmt.Println(cap(sli))  // 4
    

    五、切片的修改和追加

    1、修改

    像列表一样用[索引]取值,修改值。

    var a []int=make([]int,3,4)
    a[0]=999
    a[2]=999    //切片用[]修改值,只能取最大长度修改,超出长度的容量不能用[]的方式取值修改
    
    a[3]=100  // 不行!!!会报错
    

    2、追加:append

    使用函数 append(slice []T,x ... T)[]T 可以将新元素追加到切片上。它会有一个返回值,是追加后的新的切片,所以需要用一个值来接受一下。

    var sli []int=make([]int,3,4)
    sli = append(sli,444)
    fmt.Println(len(sli))  // 4
    fmt.Println(cap(sli))  // 4
    

    如果append函数添加的值,使切片长度超过最大容量,则会创建一个新的底层数组取代原本切片引用的数组。

    原切片的元素被复制到这个新数组中,并返回引用这个新数组的切片。

    这个新数组的长度是旧切片容量的两倍。而新切片的容量就等于这个新数组的长度。

    所以现在新切片的容量是旧切片的两倍。

    此时修改新切片的元素就不会影响原数组了。

    // make创建的切片的追加
    var sli []int=make([]int,3,4)
    fmt.Println(len(sli))  // 3
    fmt.Println(cap(sli))  // 4
    
    sli = append(sli,444)
    fmt.Println(len(sli))  // 4
    fmt.Println(cap(sli))  // 4
    
    sli = append(sli,555)
    fmt.Println(sli)       // [0 0 0 444 555]
    fmt.Println(len(sli))  // 5
    fmt.Println(cap(sli))  // 8
    
    // 引用数组的切片的追加
    var lis [10]int= [10]int{1,2,3,4,5,6,7,8,9,10}
    var sli []int = lis[5:9]
    
    fmt.Println(lis)       // [1 2 3 4 5 6 7 8 9 10]
    fmt.Println(sli)       // [6 7 8 9]
    fmt.Println(len(sli))  // 4
    fmt.Println(cap(sli))  // 5
    
    sli = append(sli,444)  
    sli[2] = 888           // 切片影响原来的数组
    fmt.Println(lis)       // [1 2 3 4 5 6 7 888 9 444]
    fmt.Println(sli)       // [6 7 888 9 444]
    fmt.Println(len(sli))  // 5
    fmt.Println(cap(sli))  // 5
    
    sli = append(sli,555)  
    sli[1] = 777           // 新的切片不会影响原来的数组了
    fmt.Println(lis)       // [1 2 3 4 5 6 7 888 9 444]
    fmt.Println(sli)       // [6 777 888 9 444 555]
    fmt.Println(len(sli))  // 6 
    fmt.Println(cap(sli))  // 10 新切片的容量是旧切片的两倍
    
    

    六、切片的函数传值

    因为切片的类型是引用类型,因此传值后,改变值会影响原来的值。

    var a []int=make([]int,4,5)
    fmt.Println(a) // [0 0 0 0]      
    test2(a)       // [111 0 0 0]
                   // [111 0 0 0 555]
    fmt.Println(a) // [111 0 0 0]
    
    
    func test2(x []int)  {
        x[0] = 111        // 修改a变量地址里的值
        fmt.Println(x)    // [111 0 0 0]
        x = append(x,555) // copy的x的长度变化了,产生了新的切片
        fmt.Println(x)    // [111 0 0 0 555]
    }
    

    七、多维切片

    一般直接初始化。

    var a [][]int=[][]int{{1,2,3},{2,3},{4,5,5,6,7,8,9}}
    fmt.Println(a)  // [[1 2 3] [2 3] [4 5 5 6 7 8 9]]
    

    八、切片的copy

    把一个切片的元素copy到另一个切片上。

    用函数copy(dst(目标), src(源))

    var a []int=make([]int,4,5)
    var b []int =[]int{1,2,3,4,5}
    
    fmt.Println(a)  // [0 0 0 0]  
    fmt.Println(b)  // [1 2 3 4 5]
    
    //把b的数据copy到a上
    copy(a,b)
    fmt.Println(a)  // [1 2 3 4]  // 长度有多少就接受多少
    fmt.Println(b)  // [1 2 3 4 5]
    
    --------------------------------------------------
    var a []int=make([]int,6,7)
    var b []int =[]int{1,2,3,4,5}
    
    fmt.Println(a)  // [0 0 0 0 0 0]
    fmt.Println(b)  // [1 2 3 4 5]
    
    //把b的数据copy到a上
    copy(a,b)
    fmt.Println(a)  // [1 2 3 4 5 0]  // 不足的用默认值补齐
    fmt.Println(b)  // [1 2 3 4 5]
    
  • 相关阅读:
    java实现快速排序
    java实现二叉树
    hudson——持续集成
    Oracle存储过程的数组参数
    在linux系统下建立artifactory管理maven库
    关于排错:专注思考,细心观察,步步为营
    在关键字'('附近有语法错误 Incorrect syntax near '(' in sql server table values function
    快速将PSD文件生成WordPress主题模板Divine
    SQLserver 复制分发( 发布与订阅) 疑难杂症 Replication (Publications,Subscriptions)
    Windows8将撼动笔记本电脑市场?
  • 原文地址:https://www.cnblogs.com/bowendown/p/12595104.html
Copyright © 2011-2022 走看看