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)
        }
    
  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/aresxin/p/GO-qie-pian.html
Copyright © 2011-2022 走看看