• golang学习笔记——基础03


    切片

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

        1. 切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
        2. 切片的长度可以改变,因此,切片是一个可变的数组。
        3. 切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。 
        4. cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
        5. 切片的定义:var 变量名 []类型,比如 var str []string  var arr []int。
        6. 如果 slice == nil,那么 len、cap 结果都等于 0。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建切片的各种方式

    package main
    
    import "fmt"
    
    func main() {
       //1.声明切片
       var s1 []int
       if s1 == nil {
          fmt.Println("是空")
       } else {
          fmt.Println("不是空")
       }
       
       // 2.:=
       s2 := []int{}
       
       // 3.make()
       var s3 []int = make([]int, 0) \\make([]type, len)
       fmt.Println(s1, s2, s3)
       
       // 4.初始化赋值
       var s4 []int = make([]int, 0, 0) \\make([]int,len,cap) 
       fmt.Println(s4)
       s5 := []int{1, 2, 3}
       fmt.Println(s5)
       
       // 5.从数组切片
       arr := [5]int{1, 2, 3, 4, 5}
       var s6 []int
       
       // 前包后不包
       s6 = arr[1:4]
       fmt.Println(s6)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    切片初始化

    全局:
    var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    var slice0 []int = arr[start:end] 
    var slice1 []int = arr[:end]        
    var slice2 []int = arr[start:]        
    var slice3 []int = arr[:] 
    var slice4 = arr[:len(arr)-1]      //去掉切片的最后一个元素
    局部:
    arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0} //注意,这个是数组
    slice5 := arr[start:end]
    slice6 := arr[:end]        
    slice7 := arr[start:]     
    slice8 := arr[:]  
    slice9 := arr[:len(arr)-1] //去掉切片的最后一个元素
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    数组与切片有时比较难以分辨,可以通过定义与规则来区分

    1. 数组,是同一种数据类型的固定长度的序列。
    2. 切片,是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。切片是一种引用类型,它有三个属性:指针,长度和容量。
    3. 数组长度必须是常量。如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度。如data := [...]int{0, 1, 2, 3, 4}
    4. 语句有make的是切片,有中括号有冒号的是切片,如[:]
    5. 下面这样不确定长度的是切片
      // [] 中括号里面是空的
      s2 := []int{}
      
      // [] 中括号里面是空的
      data := [][]int{
          []int{1, 2, 3},
          []int{100, 200},
          []int{11, 22, 33, 44},
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    go 切片扩容

    当切片的长度超过其容量时,切片会自动扩容。这通常发生在使用 append 函数向切片中添加元素时。

    扩容时,Go 运行时会分配一个新的底层数组,并将原始切片中的元素复制到新数组中。然后,原始切片将指向新数组,并更新其长度和容量。

    需要注意的是,由于扩容会分配新数组并复制元素,因此可能会影响性能。如果你知道要添加多少元素,可以使用 make 函数预先分配足够大的切片来避免频繁扩容。

    一、go1.18 之前:

    1. 如果期望容量大于当前容量的两倍就会使用期望容量;
    2. 如果当前切片的长度小于 1024 就会将容量翻倍;
    3. 如果当前切片的长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;

    二、go1.18 之后:

    1. 如果期望容量大于当前容量的两倍就会使用期望容量;
    2. 如果当前切片的长度小于阈值(默认 256)就会将容量翻倍;
    3. 如果当前切片的长度大于等于阈值(默认 256),就会每次增加 25% 的容量,基准是 newcap + 3*threshold,直到新容量大于期望容量;
    oldcap扩容系数
    2562.0
    5121.63
    10241.44
    20481.35
    40961.30

    参考

    Go 1.18 Release Notes
    Go 语言切片是如何扩容的?

  • 相关阅读:
    大数据学习1.1-Centos8网络配置
    【C++】函数重载 & 引用 & 内联函数
    opencv 矩形检测与计数
    HTML+CSS
    【读书笔记】【More Effective C++】异常(Exceptions)
    聊聊logback的StatusListener
    【Java-LangChain:面向开发者的提示工程-7】文本扩展
    ubuntu 20.04 搭建crash dump问题分析环境
    MFC 简单绘图与文本编辑
    css钟表数字样式
  • 原文地址:https://blog.csdn.net/e891377/article/details/134389639