美文网首页
Go - array、slice

Go - array、slice

作者: kyo1992 | 来源:发表于2021-05-13 23:42 被阅读0次

array

特征
  • 内存连续,可以根据索引获取元素.
  • 初始化之后大小就无法改变.
  • 存储元素类型相同、大小相同的两个数组才是一个类型
初始化
arr1 := [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3}
特殊点

在不考虑逃逸分析的情况下,如果数组中元素的个数小于或者等于 4 个,那么所有的变量会直接在栈上初始化,如果数组元素大于 4 个,变量就会在静态存储区初始化然后拷贝到栈上

slice

结构
type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}
  • Data 是指向数组中本切片第一个可用元素的指针;
  • Len 是当前切片的长度;
  • Cap 是当前切片的容量,即 Data 数组的大小.

Data 指向一片连续的内存空间,切片可以理解成一片连续的内存空间加上长度与容量的标识。

初始化
arr[0:3] or slice[0:3]
slice := []int{1, 2, 3}
slice := make([]int, 10)
  • 通过下标的方式获得数组或者切片的一部分;
  • 使用字面量初始化新的切片;
  • 使用关键字 make 创建切片.

如果当前的切片不会发生逃逸并且切片非常小(<5)的时候,会在栈上分配内存; 如果切片长度较大,或者发生内存逃逸,则会在堆上进行内存分配。

追加与扩容

追加时,当切片的容量不足,发生扩容, 为切片分配新的内存空间并拷贝原切片中元素.

扩容策略

  1. 如果期望容量大于当前容量的两倍就会使用期望容量;
  2. 如果当前切片的长度小于 1024 就会将容量翻倍;
  3. 如果当前切片的长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;
  4. 当数组中元素所占的字节大小为 1、8 或者 2 的倍数时,运行时会使用代码对齐内存, 获取的内存数量可能会稍微增多,提高内存的分配效率并减少碎片。

append结果会返回一个新的切片,其中包含了新的数组指针、大小和容量,这个返回的三元组最终会覆盖原切片

代码分析
var arr []int64
arr = append(arr, 1, 2, 3, 4, 5)

当我们执行上述代码时,会触发 runtime.growslice 函数扩容 arr 切片并传入期望的新容量 5,这时期望分配的内存大小为 40 字节;不过因为切片中的元素大小等于 sys.PtrSize,所以运行时会调用 runtime.roundupsize 向上取整内存的大小到 48 字节,所以新切片的容量为 48 / 8 = 6

切片拷贝
copy(dest, src)

在大切片上执行拷贝操作时一定要注意对性能的影响。

相关文章

  • 深入理解 Go Slice

    原文地址:深入理解 Go Slice 是什么 在 Go 中,Slice(切片)是抽象在 Array(数组)之上的特...

  • Go array & slice

    A slice does not store any data, it just describes a sect...

  • Go - array、slice

    array 特征 内存连续,可以根据索引获取元素. 初始化之后大小就无法改变. 存储元素类型相同、大小相同的两个数...

  • 彻底理解Golang Slice

    看完这篇文章,下面这些高频面试题你都会答了吧 Go slice的底层实现原理 Go array和slice的区别 ...

  • go中array与slice

    刚接触go时间不长,关于array与slice做一个笔记 eg: eg2:

  • Go中的Array和Slice

    Go中的Array和Slice 翻译来于:https://blog.golang.org/slices 操作 ex...

  • Golang Range关键字的秘密

    Go 语言中 range 关键字用于 for 循环中迭代,支持类型如下: 数组(array) 切片(slice) ...

  • golang slice && array

    array 和slice都是数组,前者固定大小,值类型;后者可以动态变更,引用类型。再次强调一遍,array在go...

  • Go语言范围(Range)

    Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channe...

  • 增强for循环 for range

    Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channe...

网友评论

      本文标题:Go - array、slice

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