Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊 Golang 中的切片和数组

聊聊 Golang 中的切片和数组

作者头像
leoay 技术
发布于 2023-06-12 06:44:56
发布于 2023-06-12 06:44:56
26600
代码可运行
举报
文章被收录于专栏:leoay 技术leoay 技术
运行总次数:0
代码可运行

字数:1467, leoay 技术圈

你好, 我是 leoay, 又好几天不见了,今天我想聊一下 Golang 中切片和数组的区别。

说到数组,我们应该都不陌生吧,因为基本上每种编程语言中有它的身影;而切片呢?也是一种数据结构,python中也有切片的概念。

数组和切片都可以用来存储一组数据。

但是不同的是数组的长度是固定的,而切片则是可变的;切片就类似于一个可变的数组。

其实,在Go语言中数组和切片外表看起来很像,也因此有时候我们很容易搞混淆,下面我就用几个例子对比一下数组和切片的差异。

数组

因为数组是固定长度的,所以在定义数组时,我们必须指定数组的长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var array1 [3] int   //长度为3的整型数组,默认值是3个0

arr := [5]int{1, 2, 3, 4, 5}   //长度为5的数组,并赋值

var array2 = [...]int{6, 7, 8}  //不声明长度,长度取总元素个数3

array3 := [...] int {1,2,3} //不声明长度的数组,长度取总元素个数3

array4 := [...] int {99:-1}  //长度为100的数组,只有最后一个是-1,其他都是0(大括号中前面一个是最大下标,后面则是对应的值)

和其他语言的数组一样, Golang 的数组也是通过下标访问元素的。

slice

slice,即切片,表示一个拥有相同类型元素的可变长度序列。

slice通常被写为[]T,其中元素的类型都是T;它看上去就像没有长度的数组类型。

数组和slice其实是紧密关联的,它们可以很方便地相互转换。

slice可以看成是一种轻量级的数据结构,可以用来访问数组的部分或者全部元素,而这个数组称之为slice的底层数组。

但是slice和数组是不同的,slice有三个属性:指针,长度和容量,而数组就没有容量这个属性。

其中,指针指向底层数组的第一个可以从slice中访问的元素,这个元素不一定是数组的第一个元素。

长度指的是slice中的元素个数,不能超过slice的容量。

容量的大小通常大于等于长度,会随着元素个数增多而动态变化。Go语言的内置函数len 和 cap 用来返回slice的长度和容量。

下面看一下怎么定义slice:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sllice1 := []int{1, 2, 3}  //注意与数组初始化的区别,在内存中构建一个包括有3个元素的数组,然后将这个数组的应用赋值给s这个Slice

array1 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}  //a是数组
slice2 := array1[2:8]    //从数组中切片构建Slice

slice3 := make([]int, 10, 20)  //make函数初始化,len=10,cap=20

从上面的例子中我们可以看出,数组和slice还是很像,我们可以通过数组构建slice,也可以直接用make创建空的slice,至于make的用法,其实在 Go 中有好几种,后面 涉及到 channel 的文章时再细说。

关于 slice 的扩容

我们已经知道了 slice 的长度不是固定,所以它支持扩容。

在 Go 中我们也用 append 函数来为 slice 扩容。但是这儿有个疑问,如果我们在定义 slice 时已经指定好了长度和容量, 那么扩容时会有什么影响呢?

一般来说,如果我们在对 slice 追加元素时, 容量不够了, 那么其容量一般按照原来的2倍进行扩容, 而长度呢,则会更新为实际的元素个数,可以通过下面这部分代码看效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main 

import "fmt"

func print_info(my_slice []int) {
 fmt.Println("len :",len(my_slice))
 fmt.Println("cap :",cap(my_slice))
 for i,v :=range my_slice{
  fmt.Println("element[",i,"]=",v)
 }
 fmt.Printf("%p", my_slice)
}

func main() {
 slice1 := make([]int,5,6)
 print_info(slice1)
 slice2 := append(slice1,8,9,10)
 print_info(slice02)
}

其实,进一步观察上面的代码,当我们把扩充前后的 slice 的地址打印出来后发现,它们是不一样的,这就说明扩充并不只是简简单单地在原来的 slice 后面追加元素,而是新创建了一个 slice。

实际上新的 slice 中的前面的元素是从原来的slice中拷贝过来的。

好了,今天的这篇文章就写到这里了,怎么样?看完以后是不是觉得对 Go 中数组和 slice 的认识又多了亿点点,如果觉得文章写得 ok,请给个点赞,以后我会花更多时间陪你在技术的海洋中遨游!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 leoay技术号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【云+社区年度征文】Go 语言切片基础知识总结
切片是一个种特殊的数组。是对数组的一个连续片段的引用,所以切片是一个引用类型。切片可以是数组中的一部分,也可以是由起始和终止索引标识的一些项的子集。切片有点像C语言里的指针,指针可以做运算,但代价是内存操作越界,切片在指针的基础上增加了大小,约束了切片对应的内存区域,切片使用中无法对切片内部的地址和大小进行手动调整,因此切片比指针更安全、强大。
兔云小新LM
2020/12/17
7370
【云+社区年度征文】Go 语言切片基础知识总结
如何更好的学习Golang中的切片数据类型
切片是一个种特殊的数组。是对数组的一个连续片段的引用,所以切片是一个引用类型。切片可以是数组中的一部分,也可以是由起始和终止索引标识的一些项的子集。切片有点像C语言里的指针,指针可以做运算,但代价是内存操作越界,切片在指针的基础上增加了大小,约束了切片对应的内存区域,切片使用中无法对切片内部的地址和大小进行手动调整,因此切片比指针更安全、强大。
兔云小新LM
2021/11/25
1.2K0
Go 数据类型篇(六):切片使用入门和数据共享问题处理
在前一篇教程里我们已经介绍过数组的一个特点:数组的长度在定义之后无法修改,数组长度是数组类型本身的一部分,是数组的一个内置常量,因此我们无法在数组上做动态的元素增删操作。
学院君
2023/03/03
4720
Go 数据类型篇(六):切片使用入门和数据共享问题处理
Golang中的数组和切片
(2)数组是值类型,将一个数组赋值给另一个数组时,会将所有的元素进行复制;切片是引用类型,将一个切片赋值给另一个切片时,它们将共享底层数组。
周小末天天开心
2023/10/16
2780
go语言中的数组切片:特立独行的可变数组
初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多。但是在使用了一段时间后,觉得这东西埋的坑不少,使用方式上和arrayList也有很大的不同,在使用时要格外注意。 slice的数据结构 首先说一下slice的数据结构,源码可以在google code上找到,http://code.google.com/p/go/source/browse/src/pkg/runtime/runtime.h struct Slice
李海彬
2018/03/26
1.1K0
Go语言进阶:数组与切片
在Go语言的世界里,数组和切片是构建高效、可靠程序的基石。它们提供了一种强大的方式来组织和管理数据集合,使得数据操作既直观又灵活。本文《Go语言进阶,数组与切片》将带领你深入探索这两种数据结构的内部机制,理解它们的本质区别,以及如何有效地使用它们来提升你的Go编程技能。
windealli
2024/03/18
2960
Go语言进阶:数组与切片
Golang之旅31-array&slice
数组和切片 数组array 可以存放多个同一类型数据 数组是种数据类型,数组是值类型 数组的地址和数组中第一个元素的地址相同 第二个元素的地址 = 第一个元素的地址 + 这个数组类型占用的字节数(int:8,int32:4) 数组中的地址是连续的,通过数组名来进行获取&intArr package main import "fmt" func main(){ var hens [4]float64 // 赋值过程 hens[0] = 1.0 hens[1] = 2.0 hens[2]
皮大大
2021/03/02
3070
Golang-绕不开的数组和切片总结
Go语言中slice和数组是非常像的两种数据结构,但是切片(slice)比数组更好用,Go更推荐slice。当然在面试中也是出现频率非常高的,总结一些数组和slice常见的问题。
小许code
2023/02/06
6210
Golang-绕不开的数组和切片总结
GO语言基础之切片
1、切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。 2、切片的长度可以改变,因此,切片是一个可变的数组。 3、切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。 4、cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。 5、切片的定义:var 变量名 []类型,比如 var str []string var arr []int。 6、如果 slice == nil,那么 len、cap 结果都等于 0。
墨紫羽墨
2022/03/01
3110
Go 语言之父详述切片与其他编程语言数组的不同
切片是Go 语言核心的数据结构,然而刚接触 Go 的程序员经常在切片的工作方式和行为表现上被绊倒。比如,明明说切片是引用类型但在函数内对其做的更改有时候却保留不下来,有时候却可以。究其原因是因为我们很多人用其他语言的思维来尝试猜测 Go 语言中切片的行为,切片这个内置类型在 Go 语言底层有其单独的类型定义,而不是我们通常理解的其他语言中数组的概念。
KevinYan
2020/02/26
1.1K0
【Go语言精进之路】构建高效Go程序:了解切片实现原理并高效使用
在Go语言中,数组是一种固定长度的数据结构,用于存储相同类型的元素。每个元素在数组中的内存地址是连续的,这使得数组的访问速度非常快。然而,数组的长度是固定的,一旦定义就无法改变,这在处理可变长度的数据集合时会显得不够灵活。
空白诗
2024/06/19
2160
【Go语言精进之路】构建高效Go程序:了解切片实现原理并高效使用
go的数据类型-复合数据类型-slice(二)
在Go语言中,可以通过make函数和切片字面量(slice literal)两种方式来创建切片。
堕落飞鸟
2023/04/19
2110
Go 复合类型之切片类型介绍
我们在上一个节Go复合类型之数组类型提到过,数组作为最基本同构类型在 Go 语言中被保留了下来,但数组在使用上确有两点不足:固定的元素个数,以及传值机制下导致的开销较大。于是 Go 设计者们又引入了另外一种同构复合类型:切片(slice),来弥补数组的这两处不足。
贾维斯Echo
2023/10/18
2760
Go 复合类型之切片类型介绍
Slice(切片)
什么是Slice(切片)? 切片是一个拥有相同类型元素的可变长度的序列.是基于数组类型做的一层封装 如何创建Slice(切片) 有两种创建方式: 可以通过已有的数组创建切片 语法: arry := [] slice1:= arry[startIndex:endIndex] number := []int{1, 3, 7, 2, 5} slice1 := number[1:3] fmt.Println(slice1) --- [3 7] 如果startIndex为空则从第一个元素开始 number
是小张啊喂
2022/08/18
8170
Go 语言基础入门教程 —— 数据类型篇:在数组切片中动态增删元素
切片比数组更强大之处在于支持动态增加元素,甚至可以在容量不足的情况下自动扩容,关于容量我们在上篇教程中已经简单提及过,在切片类型中,元素个数和实际可分配的存储空间是两个不同的值,元素的个数即切片的实际长度,而可分配的存储空间就是切片的容量。
学院君
2019/08/08
1.1K0
详解go语言的array和slice 【一】
  本篇会详细讲解go语言中的array和slice,和平时开发中使用时需要注意的地方,以免入坑。   Go语言中array是一组定长的同类型数据集合,并且是连续分配内存空间的。   声明一个数组 var arr [3]int   数组声明后,他包含的类型和长度都是不可变的.如果你需要更多的元素,你只能重新创建一个足够长的数组,并把原来数组的值copy过来。   在Go语言中,初始化一个变量后,默认把变量赋值为指定类型的zero值,如string 的zero值为"" number类型的zero值为0.数组也
lpxxn
2018/01/31
1.3K0
详解go语言的array和slice 【一】
Go语言中的数组和切片详解
在Go语言中,数组是一种具有固定大小的序列,可以存储相同类型的元素。数组的定义和初始化如下:
数字扫地僧
2024/06/14
1450
云青青兮欲雨——Go的数组与切片傻傻分不清楚?
我们在使用Go语言进行程序的编写时,不可避免会遇到切片和数组的抉择。其实我建议选切片,因为切片比数组更加好用,也更加安全。本文会比较切片与数组的异同,也会介绍切片的一些特性。
Regan Yue
2022/10/25
1480
Go 语言中同一 slice 上的切片其底层数组是否是同一个
在 Go 语言中,slice 是一个轻量级的数据结构,用于管理一组具有相同类型的元素序列。Slice 提供了一种方便且灵活的方式来操作序列数据。
GeekLiHua
2025/01/21
610
Go 语言中同一 slice 上的切片其底层数组是否是同一个
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
本文是《100天精通Golang(基础入门篇)——第11天:切片(Slice)》,将详细介绍切片的概念、语法、修改、以及len()、cap()、append()和copy()函数的使用。读者将通过学习本文深入了解Golang中切片的使用方法和常用函数的功能。
猫头虎
2024/04/08
1770
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
推荐阅读
相关推荐
【云+社区年度征文】Go 语言切片基础知识总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验