美文网首页Golang 入门资料+笔记
《GO语言圣经》学习笔记(四)切片

《GO语言圣经》学习笔记(四)切片

作者: 半亩房顶 | 来源:发表于2020-07-27 23:15 被阅读0次

切片实现原理

切片,则是由一个指向数组的指针,切片的长度和容量两个int组成

切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。

切片内存分配

区分空切片和nil切片

nil切片
空切片

一個零值的slice等於nil。一個nil值的slice併沒有底層數組。一個nil值的slice的長度和容量都是0,但是也有非nil值的slice的長度和容量也是0的,例如[]int{}或make([]int, 3)[3:]。與任意類型的nil值一樣,我們可以用[]int(nil)類型轉換表達式來生成一個對應類型slice的nil值。

var s []int    // len(s) == 0, s == nil
s = nil        // len(s) == 0, s == nil
s = []int(nil) // len(s) == 0, s == nil
s = []int{}    // len(s) == 0, s != nil

如果你需要測試一個slice是否是空的,使用len(s) == 0來判斷,而不應該用s == nil來判斷。除了和nil相等比較外,一個nil值的slice的行爲和其它任意0産長度的slice一樣;例如reverse(nil)也是安全的。除了文檔已經明確説明的地方,所有的Go語言函數應該以相同的方式對待nil值的slice和0長度的slice。

內置的make函數創建一個指定元素類型、長度和容量的slice。容量部分可以省略,在這種情況下,容量將等於長度。

make([]T, len)
make([]T, len, cap) // same as make([]T, cap)[:len]

在底層,make創建了一個匿名的數組變量,然後返迴一個slice;隻有通過返迴的slice才能引用底層匿名的數組變量。在第一種語句中,slice是整個數組的view。在第二個語句中,slice隻引用了底層數組的前len個元素,但是容量將包含整個的數組。額外的元素是留給未來的增長用的。

切片的扩容原理

go中数组不可扩容,跳过不做讨论。slice扩容规则如下:

  • 如果切片的容量小于1024个元素,那么扩容的时候slice的cap就翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加原来容量的四分之一。
  • 如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。
    我们用一个例子来加深理解,请说出输出结果:
package main

import (
    "fmt"
)

func main() {
    arr := [4]int{10, 20, 30, 40}
    slice := arr[0:2]
    testSlice1 := slice
    testSlice2 := append(append(append(slice, 1), 2), 3)
    slice[0] = 11

    fmt.Println(testSlice1[0])
    fmt.Println(testSlice2[0])
}

根据第二条规则,append三个元素后,slice超出了原本的arr的长度,已经变成了一个新的切片,所以slice[0]=11不再能影响testSlice2,输出结果:

11
10

更新slice变量不仅对调用append函数是必要的,实际上对任何可能导致长度、容量或底层数组变化的操作都是必要的

引用


欢迎大家关注我的公众号


半亩房顶

相关文章

  • 《GO语言圣经》学习笔记(四)切片

    切片实现原理 切片,则是由一个指向数组的指针,切片的长度和容量两个int组成 切片的长度就是它所包含的元素个数。切...

  • 笨办法学golang(四)

    这是Go语言学习笔记的第四篇 Go语言学习笔记参考书籍「Go语言圣经」以及Go官方标准库 数组 数组是指一系列同类...

  • 笨办法学golang(三)

    这是Go语言学习笔记第三篇。 Go语言学习笔记参考书籍「Go语言圣经」以及Go官方标准库 Go语言基本类型主要有布...

  • 《GO语言圣经》学习笔记(一)

    前言 终于开坑go语言圣经了,本系列笔记中会记录学习《GO语言圣经》中看到的知识点和引申学习。好的,话不多说,开始...

  • Golang聚合

    教程 Go Web 编程Go语言圣经(中文版) Tips Golang 学习笔记——交叉编译 & 部署Golang...

  • Go语言切片

    // //Go语言切片 // /* // go语言切片是对数组的抽象 // Go 数组的长度不可改变,在特定场景中...

  • Go语言切片学习

    切片的三种定义

  • Go语言探索 - 11(原创)

    Go语言基础系列博客用到的所有示例代码 上一篇文章主要学习了Go语言的切片以及Map。本篇文章主要学习的是Go语言...

  • Go语言探索 - 10(原创)

    上一篇文章主要学习了Go语言的结构体以及结构体指针,本篇文章主要学习Go语言的切片以及Map。 Go语言数组的长度...

  • 七、Go切片

    七、Go语言切片(Slice) Go 语言切片是对数组的抽象。 Go 数组的长度不可改变,在特定场景中这样的集合就...

网友评论

    本文标题:《GO语言圣经》学习笔记(四)切片

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