Go语言建议多使用切片少使用数组原理探究
介绍
在 Go 语言中,数组固定长度,切片可变长度;数组和切片都是值传递,因为切片传递的是指针,所以切片也被称为“引用传递”。
读者朋友们在使用 Go 语言开发项目时,或者在阅读 Go 开源项目源码时,发现很少使用到数组,经常使用到切片。
本文通过讲解 Golang 切片的一些特性,介绍 Go 语言为什么建议多使用切片,少使用数组。
切片
切片的底层是数组,它是可变长度,可以在容量不足时自动扩容。
type SliceHeader struct { Data uintptr Len int Cap int }
阅读上面这段代码,SliceHeader
结构体是切片在运行时的表现,由 3 部分组成,分别是指向底层数组的指针 Data
,长度 Len
和容量 Cap
。
声明方式
切片的声明方式有多种,分别是:
var s1 []int var s2 []int{1, 2, 3} var s3 []int = make([]int, 3) var s4 []int = make([]int, 3, 5)
阅读上面这段代码,s1
只声明未初始化,值为 nil
;s2
字面量初始化,编译时会自动推断切片的长度,容量与长度相同;
s3
声明切片,并使用内置函数 make
初始化切片的长度为 3
,因为未指定容量,所以容量与长度相同;s4
声明切片,并使用内置函数 make
初始化切片的长度为 3
,切片的容量为 5
,容量必须大于等于长度。
字面量初始化与使用内置函数 make
初始化的区别是,字面量初始化,编译时在数据区创建一个数组,并在堆区创建一个切片,程序启动时将数据区的数据复制到堆区;
使用内置函数 make
初始化,编译时根据切片大小判断分配到栈区,还是分配到堆区,小于 64KB 则分配到栈区,大于等于 64KB 则分配到堆区。
数组则是根据数组长度判定是否在栈区初始化,数组长度小于 4 时,编译时在栈区初始化数组。
引用传递
数组和切片在作为函数参数传递时,属于值传递,如果使用数组,特别是大数组时,我们需要特别小心,可以考虑使用数组指针;如果使用切片,本身就是拷贝的内存地址,所以切片也被称为“引用传递”。
自动扩容
切片可以使用内置函数 append
追加元素到切片,如果原切片容量不足时,切片可以自动扩容;数组是固定长度,如果数组长度不足时,编译时则报错,或者只能声明一个新数组,并将旧数组中的数据拷贝到新数组。
需要注意的是,虽然使用内置函数 append
追加元素,当切片容量不足时可以自动扩容切片,但是会涉及到内存分配,原切片容量小于 1024,新切片容量是原切片容量的 2 倍;
如果原切片容量大于等于 1024,新切片容量按照原切片容量的 1/4 步长循环扩容,直到新切片的容量大于等于新切片的长度为止。
总结
本文我们介绍 Go 语言为什么建议多使用切片,少使用数组。
主要是因为切片值传递的成本更低,更加适合作为函数参数,并且使用内置函数 append
追加切片元素时,当切片容量不足时可以自动扩容。
需要注意的是,虽然切片可以自动扩容,但在扩容时会涉及内存分配,造成系统开销,尽量在创建切片时,预估出切片的最终容量。
以上就是Go语言建议多使用切片少使用数组原理探究的详细内容,更多关于Go语言切片数组的资料请关注脚本之家其它相关文章!
相关文章
go-zero接入skywalking实现链路追踪的详细教程
SkyWalking是一个开源的服务追踪系统,它专注于分布式系统的可观测性和服务性能分析,它的主要目标是帮助开发者理解和优化微服务架构中的服务间交互情况,本文介绍了go-zero接入skywalking链路追踪的详细教程,需要的朋友可以参考下2024-08-08关于go-micro与其它gRPC框架之间的通信问题及解决方法
在之前的文章中分别介绍了使用gRPC官方插件和go-micro插件开发gRPC应用程序的方式,都能正常走通。不过当两者混合使用的时候,互相访问就成了问题,下面通过本文给大家讲解下go-micro与gRPC框架通信问题,一起看看吧2022-04-04go语言题解LeetCode1299将每个元素替换为右侧最大元素
这篇文章主要为大家介绍了go语言LeetCode刷题1299将每个元素替换为右侧最大元素示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-01-01
最新评论