golang 基础(15)slice 的操作

作者: zidea | 来源:发表于2019-03-18 05:49 被阅读28次
    square-gopher.png

    slice 的操作

    Slice-Bread-Step-27.jpg

    slice 添加元素

    s := arr[2:6]
        fmt.Println(cap(s)) //6
        fmt.Println(len(s)) //4
    
        s1 := s[3:5]
        fmt.Println("s = ",s)
        fmt.Println("s1 = ",s1)
    
        s2 := append(s1,10)
        s3 := append(s2,11)
        s5 := append(s3,12)
    s2, s3, s5 =  [5 6 10] [5 6 10 11] [5 6 10 11 12]
    
    s6 := append(s5,15)
        
        fmt.Println("s2, s3, s5 = ", s2, s3, s5,s6)
        fmt.Println("arr = ",arr)
    
    s2, s3, s5 =  [5 6 10] [5 6 10 11] [5 6 10 11 12] [5 6 10 11 12 15]
    arr =  [0 1 2 3 4 5 6 10]
    

    从输出接口来看 arr 还是保持原有长度,从 s3 开始以后 slice 不再是 arr 的片段,而是系统新建一个 arr

    向 slice 添加元素时

    • 添加元素时如果超越 cap, 系统会重新分配更大的底层数组,会将整个原有数组复制过去。如果原来数组不在被使用,就会被 GC 掉。
    • 由于值传递的关系,必须接收 append 的返回值
      [slice_append.JPG]
    a := make([]int, 7,15)
        b :=a[3:7]
        z := len(b)
        fmt.Println(z)
        z = cap(b)
        fmt.Println(z)
    
    func foo() []int{
        var a [5]int
        return a[:]
    }
    

    创建一个 slice 然后通过 append 不断向 slice 进行添加值,看一看整个 slice 随着值增加,他的 len 和 cap 是如何变化的。

    func printSlice(s []int){
        fmt.Printf("len=%d, cap%d\n", len(s), cap(s))
    }
    
    func main(){
        var s []int 
    
        for i := 0; i < 100; i++{
            printSlice(s)
            s = append(s, 2 * i + 1)
        }
        fmt.Println(s)
    }
    

    输出

    len=0, cap0
    len=1, cap1
    len=2, cap2
    len=3, cap4
    len=4, cap4
    len=5, cap8
    len=6, cap8
    len=7, cap8
    len=8, cap8
    len=9, cap16
    len=10, cap16
    len=11, cap16
    len=12, cap16
    len=13, cap16
    len=14, cap16
    len=15, cap16
    len=16, cap16
    len=17, cap32
    len=18, cap32
    len=19, cap32
    len=20, cap32
    len=21, cap32
    len=22, cap32
    len=23, cap32
    len=24, cap32
    len=25, cap32
    len=26, cap32
    len=27, cap32
    len=28, cap32
    len=29, cap32
    len=30, cap32
    len=31, cap32
    len=32, cap32
    len=33, cap64
    len=34, cap64
    len=35, cap64
    len=36, cap64
    len=37, cap64
    len=38, cap64
    len=39, cap64
    len=40, cap64
    len=41, cap64
    len=42, cap64
    len=43, cap64
    len=44, cap64
    len=45, cap64
    len=46, cap64
    len=47, cap64
    len=48, cap64
    len=49, cap64
    len=50, cap64
    len=51, cap64
    len=52, cap64
    len=53, cap64
    len=54, cap64
    len=55, cap64
    len=56, cap64
    len=57, cap64
    len=58, cap64
    len=59, cap64
    len=60, cap64
    len=61, cap64
    len=62, cap64
    len=63, cap64
    len=64, cap64
    len=65, cap128
    len=66, cap128
    len=67, cap128
    len=68, cap128
    len=69, cap128
    len=70, cap128
    len=71, cap128
    len=72, cap128
    len=73, cap128
    len=74, cap128
    len=75, cap128
    len=76, cap128
    len=77, cap128
    len=78, cap128
    len=79, cap128
    len=80, cap128
    len=81, cap128
    len=82, cap128
    len=83, cap128
    len=84, cap128
    len=85, cap128
    len=86, cap128
    len=87, cap128
    len=88, cap128
    len=89, cap128
    len=90, cap128
    len=91, cap128
    len=92, cap128
    len=93, cap128
    len=94, cap128
    len=95, cap128
    len=96, cap128
    len=97, cap128
    len=98, cap128
    len=99, cap128
    [1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199]
    
    func printSlice(s []int){
        fmt.Printf("%v, len=%d, cap%d\n", s, len(s), cap(s))
    }
    

    然后使用其他创建方式在创建 slice

        s1 := []int{2, 4, 6, 8}
        printSlice(s1)
        s2 := make([]int,16) //指定长度为16
        printSlice(s2)
        s3 := make([]int, 10, 32) //指定长度为 10 可扩展 32
        printSlice(s3)
    

    输出

    [2 4 6 8], len=4, cap4
    [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap16
    [0 0 0 0 0 0 0 0 0 0], len=10, cap32
    

    复制 slice

    copy(s2,s1)
        printSlice(s2)
    

    输出

    [2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap16
    

    删除一个元素

        // s2[:3] + s2[4:]
        fmt.Println("before deleting s2 = ", s2)
        s2 = append(s2[:3],s2[4:]...)
        fmt.Println("after deleting s2 = ", s2)
    

    其实 append 函数,看一看 append(slice []Type, elems ...Type) [] Type 源码,append 第二参数是一个可变的参数,那么可以将 slice... 先将 slice 解构为一个一个的元素,然后作为参数传进去。
    输出

    before deleting s2 =  [2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0]
    after deleting s2 =  [2 4 6 0 0 0 0 0 0 0 0 0 0 0 0]
    

    pop 和 tail 方法

    在其他语言中基本提供了集合这样操作,不过 go 应该最求极简主义吧,如果能有基本方法实现的方法,作者就不愿追加这些方法。

    fmt.Println("Popping from front")
        front := s2[0]
        s2 = s2[1:]
    
        fmt.Println("Popping from back")
        tail := s2[len(s2) - 1]
        s2 = s2[:len(s2) - 1]
    
    images.png

    相关文章

      网友评论

        本文标题:golang 基础(15)slice 的操作

        本文链接:https://www.haomeiwen.com/subject/rmjmmqtx.html