zoukankan      html  css  js  c++  java
  • GO切片

    切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。
    切片是一个引用类型(直接引用的内存地址),它的内部结构包含地址、长度和容量。切片一般用于快速地操作一块数据集合。
    切片是引用类型,不支持直接比较,只能和nil比较!

    得到切片的三种方式:

    • 直接声明a := []int{1,2,3} len:3 cap:3
    • 基于数组得到切片 m := [5]int b:= m[:3] len:3, cap:5,数组发生改变,切片随即发生改变,反之亦然
    • 基于切片得到切片 b := a[:2] len:2 cap:3

    切片定义

    基本语法:var name []T
    name:变量名
    T:切片中元素类型
    切片定义

    //基本声明:直接定义
        var a []int     //声明一个切片
        var b = []int{1,2,3}    //声明一个切片并且初始化
        a = []int{1,3,5}
        fmt.Println(a)  //[1 3 5]
        fmt.Println(b)  //[1 2 3]
        //从数组中定义
        c := [4]int{1,2,3,4}
        c1 := c[0:2]    //包含元素c[0],c[1],左包含右不包含
        fmt.Println(c1) //[1 2]
        fmt.Printf("type of c1:%T
    ", c1)       //type of c1:[]int
        c2 := c[1:]     //从索引1开始切到最后
        c3 := c[:3]     //从开始切到索引为3(不包含3,3-1)
        fmt.Println(c2) //[2 3 4]
        fmt.Println(c3) //[1 2 3]
    

    切片扩容

    Go语言的内建函数append()可以为切片动态添加元素。
    示例:

    //切片扩容
        s := []int{}    //定义一个空切片
        //var s []int   //定义一个空切片
        for i:=0;i<10;i++{
            s = append(s, i)
            fmt.Printf("%v  len:%d  cap:%d ptr:%p
    ",s,len(s),cap(s),s)
        }
    //输出
    [0]  len:1  cap:1 ptr:0xc42000e318
    [0 1]  len:2  cap:2 ptr:0xc42000e340
    [0 1 2]  len:3  cap:4 ptr:0xc42000a360
    [0 1 2 3]  len:4  cap:4 ptr:0xc42000a360
    [0 1 2 3 4]  len:5  cap:8 ptr:0xc4200161c0
    [0 1 2 3 4 5]  len:6  cap:8 ptr:0xc4200161c0
    [0 1 2 3 4 5 6]  len:7  cap:8 ptr:0xc4200161c0
    [0 1 2 3 4 5 6 7]  len:8  cap:8 ptr:0xc4200161c0
    [0 1 2 3 4 5 6 7 8]  len:9  cap:16 ptr:0xc42007a000
    [0 1 2 3 4 5 6 7 8 9]  len:10  cap:16 ptr:0xc42007a000
    
    • append()函数将元素追加到切片的最后并返回该切片。
    • 切片numSlice的容量按照1,2,4,8,16这样的规则自动进行扩容。
    • 如果新申请容量(cap)大于2倍的旧容量(old.cap),最终容量(newcap)就是新申请的容量(cap)。
    • 如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap)
    • 如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
    • 如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)。

    切片是引用类型

    //对一个切片的修改会影响另一个切片的内容
        a := []int{1,2,3}
        b := a  //直接赋值
        b[1] = 10
        fmt.Println(a)  //[1 10 3]
        fmt.Println(b)  //[1 10 3]
    

    由于切片是引用类型,所以a和b其实都指向了同一块内存地址。修改b的同时a的值也会发生变化。

    make()函数构造切片

    如果需要动态的创建一个切片,我们就需要使用内置的make()函数。
    语法:make([]T, size, cap)
    T:切片的元素类型
    size:切片中元素的数量
    cap:切片的容量
    make用于给引用类型申请内存空间
    切片必须初始化,或者用append才能使用

    //make函数
        s := make([]int,2,5)
        fmt.Println(s)      //[0 0]
        fmt.Println(len(s)) //2
        fmt.Println(cap(s)) //5
    

    s的内部存储空间已经分配了5个,但实际上只用了2个.

    copy()函数复制切片

    Go语言内建的copy()函数可以迅速地将一个切片的数据复制到另外一个切片空间中,修改copy后切片的值不会影响原切片。
    语法:copy(destSlice, srcSlice []T)
    srcSlice: 数据来源切片
    destSlice: 目标切片

    a := []string{"北京","上海"}
        var b []string  //还没有申请内存,所以打印为[]
        copy(b,a)
        fmt.Println(a)  //[北京 上海]
        fmt.Println(b)  //[]
        c := make([]string,3,3)
        copy(c,a)
        fmt.Println(c)      //[北京 上海 ]
        c[0] = "青岛"
        fmt.Println(c)      //[青岛 上海 ]
        fmt.Println(a)      //[北京 上海]
    

    切片删除元素

    Go语言中并没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素。

    //切片中删除元素
        d := []int{1,2,3,4,5,6,7}
        //删除索引为2的元素
        d = append(d[:2],d[3:]...)
        fmt.Println(d)  //[1 2 4 5 6 7]
    

    总结:要从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]...)

    切片遍历

    支持索引遍历和for range遍历。

    //切片遍历
        a1 := []string{"北京","上海"}
        for i:=0;i<len(a1);i++{
            fmt.Println(a1[i])
        }
        for k,v :=range a1{
            fmt.Println(k,v)
        }
    
  • 相关阅读:
    3.5 操作系统习题
    04_jni开发常见错误_本地方法没有找到
    3.4 目录和spooling
    3.3 作业管理
    03_jni_helloworld_完成
    ASP.NET MVC 4 过滤器(Authorize)
    MVC实现实现文件流打包成压缩包
    MVC实现实现文件流打包成压缩包
    MVC实现实现文件流打包成压缩包
    图解分布式架构的演进过程!
  • 原文地址:https://www.cnblogs.com/aresxin/p/GO-qie-pian.html
Copyright © 2011-2022 走看看