Go 语言为什么建议多使用切片,少使用数组?
大家好,我是 frank,「Golang 语言开发栈」公众号作者。
01 介绍
在 Go 语言中,数组固定长度,切片可变长度;数组和切片都是值传递,因为切片传递的是指针,所以切片也被称为“引用传递”。
读者朋友们在使用 Go 语言开发项目时,或者在阅读 Go 开源项目源码时,发现很少使用到数组,经常使用到切片。
本文通过讲解 Golang 切片的一些特性,介绍 Go 语言为什么建议多使用切片,少使用数组。
02 切片
切片的底层是数组,它是可变长度,可以在容量不足时自动扩容。
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 步长循环扩容,直到新切片的容量大于等于新切片的长度为止。
03 总结
本文我们介绍 Go 语言为什么建议多使用切片,少使用数组。
主要是因为切片值传递的成本更低,更加适合作为函数参数,并且使用内置函数 append 追加切片元素时,当切片容量不足时可以自动扩容。
需要注意的是,虽然切片可以自动扩容,但在扩容时会涉及内存分配,造成系统开销,尽量在创建切片时,预估出切片的最终容量。
Go 语言为什么建议多使用切片,少使用数组?的更多相关文章
- Go语言类型(布尔、整型、数组、切片、map等)
1.基本类型 布尔类型:bool 注意:布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换. 整型:int8.byte(uint8).int16.int.uint.uintptr int.ui ...
- Go语言学习笔记十一: 切片(slice)
Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...
- 《Go语言实战》笔记之第四章 ----数组、切片、映射
原文地址: http://www.niu12.com/article/11 ####数组 数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块. 数组存储的类型可以是内置类型,如整型 ...
- go语言之切片即动态数组
切片和数组的类型有什么不一样,我们可以打印一下,就可以知道两者的区别了,数组是容量的,所以中括号中有容量,切片的动态数组,是没有容量,这是数组和切片最大的区别 test8_4 := [20] int ...
- C语言学习建议!8年编程开发经验
C语言是几乎所有编程语言的先驱与灵感的来源,Perl,PHP,Python和Ruby都是用它写的,同样什么Microsoft Windows,Mac OS X,还有GNU/Linu这些操作系统,都是靠 ...
- Golang语言系列-05-数组和切片
数组和切片 数组 概念 数组是同一种数据类型元素的集合:数组的长度必须是常量,并且长度是数组类型的一部分,一旦定义,长度不能变 例如:[5]int 和 [10]int 是不同的数组类型 使用时可以修改 ...
- Go语言基础五:引用类型-切片和映射
切片 Go的数组长度不可以改变,在某些特定的场景中就不太适用了.对于这种情况Go语言提供了一种由数组建立的.更加灵活方便且功能强大的包装(Wapper),也就是切片.与数组相比切片的长度不是固定的,可 ...
- go语言基础之切片和底层数组关系
1.切片和底层数组关系 示例: package main //必须有个main包 import "fmt" func main() { a := []int{0, 1, 2, 3, ...
- 【原创】go语言学习(八)切片
目录: 切片定义 切片基本操作 切片传参 make和new的区别 切片定义 1. 切片是基于数组类型做的一层封装.它非常灵活,可以自动扩容. var a []int //定义一个int类型的空切⽚ 2 ...
- 快乐编程大本营【java语言训练班】第5课: java的数组编程
快乐编程大本营[java语言训练班]第5课: java的数组编程 第1节. 声明数组变量 第2节. 创建数组对象 第3节. 访问数组元素 第4节. 修改数组元素 第5节. 多维数组 学习地址如下:ht ...
随机推荐
- #POWERBI_指标监控(第二部分,周期内下降天数及日期明细)
在指标监控的第一部分文章中,我们已经讲了,如何用DAX去查询一段周期内连续下降或者上升指标. 需要复习的同学可以点击下方链接: https://www.cnblogs.com/simone331/p/ ...
- asp.net mvc Core 网页错误提示:An unhandled exception occurred while processing the request.处理请求时发生未处理的异常。
网页错误提示: An unhandled exception occurred while processing the request. InvalidOperationException: The ...
- MySQL系列之——错误日志(log_error)、二进制日志(binary logs)、慢日志(slow_log)
文章目录 1.错误日志(log_error) 1.1 作用 1.2 错误日志配置 1.3 日志内容查看 2. binlog(binary logs):二进制日志 ***** 2.1 作用 2.2 bi ...
- $GNRMC
$GNRMC 格式: $GNRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,&l ...
- P9140 [THUPC 2023 初赛] 背包
prologue 这很难评(调了我 1h,我都想紫砂了. 还是典型得不重构就看不见系列. analysis 如果我们还是一个正常人,那么我们大体上是能看到题目的加粗字,这个格式很明显符合我们的同余最短 ...
- RK3588平台产测之ArmSoM产品低温环境测试
1. 简介 专栏总目录 ArmSoM团队在产品量产之前都会对产品做几次专业化的功能测试以及性能压力测试,以此来保证产品的质量以及稳定性 优秀的产品都要进行严苛的多次全方位的功能测试以及性能压力测试才能 ...
- 【BUU刷题日记】——第一周
[BUU刷题日记]--第一周 一.[极客大挑战 2019]PHP1 题目说自己有一个备份网站的习惯,所以要了解一下常见的网站源码备份格式及文件名: 格式:tar.tar.gz.zip.rar 文件名: ...
- AI图形算法之一:液位计识别
AI人工智能的主要应用之一就是图形化处理和识别,之前写了两篇,分别是: AI图形算法的应用之一:通过图片模板对比发现油田漏油 AI图形算法的应用之一:仪表识别 经过几个晚上的辛苦,液位计识别也测试成功 ...
- 探究-ping指令的使用
简介: 背景:一直以来在项目上经常使用ping指令来测试网络通信,最近稍微研究了一下常用的指令,记录以作备忘.--MaQaQ 2023-11-1 ping (Packet Internet Grope ...
- XML文件的解析--libxml库函数解释
[c语言]XML文件的解析--libxml库函数解释 2009-09-02 13:12 XML文件的解析--libxml库函数解释 libxml(一) ...