zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    NOIP201208同余方程
    NOIP模拟赛 最佳组合
    NOIP模拟赛 拓展
    CF1253E Antenna Coverage(DP)
    LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)
    CF582E Boolean Function(DP,状态压缩,FMT)
    CF750G New Year and Binary Tree Paths(DP)
    Codeforces Round 596 题解
    AGC008E Next or Nextnext(组合计数,神奇思路)
    ARC082E ConvexScore(神奇思路)
  • 原文地址:https://www.cnblogs.com/jiangchunsheng/p/10753144.html
Copyright © 2011-2022 走看看