• Go语言切片


    Go语言切片是对数组的抽象。数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的可以追加元素,在追加时可能使切片的容量增大。

    需要说明,slice 并不是数组或数组指针。它通过内部指针和相关属性引用数组片段,以实现变长方案。

    切片定义

    第一种,声明一个切片:

    var slice []int

    切片定义并初始化

    var slice0 []int = []int{1, 2, 3}
    var slice1 = []int{1, 2, 3}

    第二种,通过make来创建切片

    var slice0 []int = make([]int, 10)
    var slice1 = make([]int, 10)
    var slice2 = make([]int, 10, 10)

    第三种,通过 := 语法来定义切片

    slice0 := []int{}
    slice1 := make([]int, 10)
    slice2 := make([]int, 10, 10)

    第四种,通过操作数组来创建切片

    ar array = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    var slice0 []int = array[2:8]
    
    // 可以简写为 var slice []int = array[:end]
    var slice1 []int = array[0:6]
    
    // 可以简写为 var slice[]int = array[start:]
    var slice2 []int = array[5:10]
    
    // 可以简写为var slice []int = array[:]
    var slice3 []int = array[0:len(array)]
    
    // 去掉切片的最后一个元素
    var slice4 = array[:len(array)-1]

    第五种,通过两个冒号创建切片,slice[x:y:z]切片实体[x:y],切片长度len = y-x,切片容量cap = z-x

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        slice1 := slice[6:8]
        fmt.Printf("slice1 : %v , len : %d , cap : %d
    ", slice1, len(slice1), cap(slice1))
        slice2 := slice[2:6:8]
        fmt.Printf("slice2 : %v , len : %d , cap : %d
    ", slice2, len(slice2), cap(slice2))
    }

    slice1[6:8],从第6位到第8位(返回[6 7]),长度len为2,最大可扩充长度cap为4

    slice2[2:6:8],从第2位到第6位(返回[2 3 4 5]),长度len为4,最大可扩充长度cap为6

    切片操作

    切片长度,可以由 len() 函数获取切片长度。
    切片容量,可以由 cap() 函数获取切片最长可以达到多少。

    package main
    
    import "fmt"
    
    func main() {
        // 通过初始化表达式构造,可使用索引号。
        s1 := []int{0, 1, 2, 3, 8: 100}
        fmt.Println(s1, len(s1), cap(s1))
    
        // 使用 make 创建,指定 len 和 cap 值。
        s2 := make([]int, 6, 8)
        fmt.Println(s2, len(s2), cap(s2))
    
        // 省略 cap,相当于 cap = len。
        s3 := make([]int, 6)
        fmt.Println(s3, len(s3), cap(s3))
    }

    如果 slice == nil,那么 len、cap 结果都等于 0。

    切片追加,使用append() 函数向 slice 尾部添加数据,返回新的 slice

    package main
    
    import (
        "fmt"
    )
    
    func main() {
    
        var a = []int{1, 2, 3}
    
        // 一次 append 一个值
        b := append(a, 4)
    
        // 一次 append 多个值
        c := append(b, 5, 6, 7)
    
        // 一次 append 一个切片
        var d = []int{8, 9, 10}
        e := append(c, d...)
    
        fmt.Println(a, b, c, d, e)
    }

    切片拷贝,使用copy() 函数 copy 在两个 slice 间复制数据,复制长度以 len 小的为准。两个 slice 可指向同一底层数组,允许元素区间重叠。

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var a = []int{1, 2, 3, 4, 5}
        b := []int{100, 200}
        copy(a, b)
        fmt.Println(a, b)
    }

    运行结果:

    [100 200 3 4 5] [100 200]
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var a = []int{1, 2, 3, 4, 5}
        b := []int{100, 200}
        copy(b, a)
        fmt.Println(a, b)
    }

    运行结果:

    [1 2 3 4 5] [1 2]

    slice中cap重新分配规律:

    没有固定长度 GO 自动给分配容量 以 2倍的方式

    package main
    
    import (
        "fmt"
    )
    
    func main() {
    
        s := make([]int, 0, 1)
        c := cap(s)
    
        for i := 0; i < 50; i++ {
            s = append(s, i)
            if n := cap(s); n > c {
                fmt.Printf("cap: %d -> %d
    ", c, n)
                c = n
            }
        }
    
    }

    运行结果:

    cap: 1 -> 2
    cap: 2 -> 4
    cap: 4 -> 8
    cap: 8 -> 16
    cap: 16 -> 32
    cap: 32 -> 64
  • 相关阅读:
    ubuntu ip
    [转]caffe+Ubuntu14.0.4 64bit 环境配置说明(无CUDA,caffe在CPU下运行) --for --Amd
    kali install fcitx
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 叁
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 叁
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 叁
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 叁
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰
    [转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰
  • 原文地址:https://www.cnblogs.com/jiangchunsheng/p/10753144.html
Copyright © 2020-2023  润新知