Go语言建议多使用切片少使用数组原理探究

 更新时间:2024年01月07日 10:17:42   作者:frank  
这篇文章主要为大家介绍了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 只声明未初始化,值为 nils2 字面量初始化,编译时会自动推断切片的长度,容量与长度相同;

s3 声明切片,并使用内置函数 make 初始化切片的长度为 3,因为未指定容量,所以容量与长度相同;s4 声明切片,并使用内置函数 make 初始化切片的长度为 3,切片的容量为 5,容量必须大于等于长度。

字面量初始化与使用内置函数 make 初始化的区别是,字面量初始化,编译时在数据区创建一个数组,并在堆区创建一个切片,程序启动时将数据区的数据复制到堆区;

使用内置函数 make 初始化,编译时根据切片大小判断分配到栈区,还是分配到堆区,小于 64KB 则分配到栈区,大于等于 64KB 则分配到堆区。

数组则是根据数组长度判定是否在栈区初始化,数组长度小于 4 时,编译时在栈区初始化数组。

引用传递

数组和切片在作为函数参数传递时,属于值传递,如果使用数组,特别是大数组时,我们需要特别小心,可以考虑使用数组指针;如果使用切片,本身就是拷贝的内存地址,所以切片也被称为“引用传递”。

自动扩容

切片可以使用内置函数 append 追加元素到切片,如果原切片容量不足时,切片可以自动扩容;数组是固定长度,如果数组长度不足时,编译时则报错,或者只能声明一个新数组,并将旧数组中的数据拷贝到新数组。

需要注意的是,虽然使用内置函数 append 追加元素,当切片容量不足时可以自动扩容切片,但是会涉及到内存分配,原切片容量小于 1024,新切片容量是原切片容量的 2 倍;

如果原切片容量大于等于 1024,新切片容量按照原切片容量的 1/4 步长循环扩容,直到新切片的容量大于等于新切片的长度为止。

总结

本文我们介绍 Go 语言为什么建议多使用切片,少使用数组。

主要是因为切片值传递的成本更低,更加适合作为函数参数,并且使用内置函数 append 追加切片元素时,当切片容量不足时可以自动扩容。

需要注意的是,虽然切片可以自动扩容,但在扩容时会涉及内存分配,造成系统开销,尽量在创建切片时,预估出切片的最终容量。

以上就是Go语言建议多使用切片少使用数组原理探究的详细内容,更多关于Go语言切片数组的资料请关注脚本之家其它相关文章!

相关文章

  • Golang中的包及包管理工具go mod详解

    Golang中的包及包管理工具go mod详解

    这篇文章主要介绍了Golang中的包及包管理工具go mod,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Golang检查变量类型的四种方式

    Golang检查变量类型的四种方式

    Go提供几种方法检查变量的类型,在字符串格式化标识%T, 反射方式:reflect.TypeOf, reflect.ValueOf.Kind,另外还有使用类型断言,switch case方式,下面通过实例分别介绍这四类方法,需要的朋友可以参考下
    2022-10-10
  • golang使用map支持高并发的方法(1000万次操作14ms)

    golang使用map支持高并发的方法(1000万次操作14ms)

    这篇文章主要介绍了golang使用map支持高并发的方法(1000万次操作14ms),本文给大家详细讲解,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • 详解Golang五种原子性操作的用法

    详解Golang五种原子性操作的用法

    本文主要介绍了详解Golang五种原子性操作的用法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 详解Go语言的context包从放弃到入门

    详解Go语言的context包从放弃到入门

    这篇文章主要介绍了Go语言的context包从放弃到入门,本文通过实例演示给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 玩转Go命令行工具Cobra

    玩转Go命令行工具Cobra

    这篇文章主要介绍了玩转Go命令行工具Cobra,本文介绍了Cobra的最基本也是最常用的使用部分,但是Cobra仍然有很多优秀的操作值得我们学习,需要的朋友可以参考下
    2022-08-08
  • Golang实现基于时间的一次性密码TOTP

    Golang实现基于时间的一次性密码TOTP

    基于时间的一次性密码 TOTP 是 OTP 的一种实现方式,这种方法的优点是不依赖网络,因此即使在没有网络的情况下,用户也可以生成密码,下面我们就来看看如何使用golang实现一次性密码TOTP吧
    2023-11-11
  • Go语言的GOPATH与工作目录详解

    Go语言的GOPATH与工作目录详解

    这篇文章主要介绍了Go语言的GOPATH与工作目录详解,本文详细讲解了GOPATH设置、应用目录结构、编译应用等内容,需要的朋友可以参考下
    2014-10-10
  • 深入学习Golang并发编程必备利器之sync.Cond类型

    深入学习Golang并发编程必备利器之sync.Cond类型

    Go 语言的 sync 包提供了一系列同步原语,其中 sync.Cond 就是其中之一。本文将深入探讨 sync.Cond 的实现原理和使用方法,帮助大家更好地理解和应用 sync.Cond,需要的可以参考一下
    2023-05-05
  • Go的os/exec执行超时导致程序死机的解决方案

    Go的os/exec执行超时导致程序死机的解决方案

    这篇文章主要介绍了Go的os/exec执行超时导致程序死机的几种解决方案,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-04-04

最新评论