千家信息网

Go语言中的数组和切片实例分析

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍了Go语言中的数组和切片实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go语言中的数组和切片实例分析文章都会有所收获,下面我们一起来看看吧。1.
千家信息网最后更新 2026年11月04日Go语言中的数组和切片实例分析

这篇文章主要介绍了Go语言中的数组和切片实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go语言中的数组和切片实例分析文章都会有所收获,下面我们一起来看看吧。

1. 数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,因此在 Go 语言中很少直接使用数组。和数组对应的类型是 Slice(切片),它是可以增长和收缩的动态序列,slice 功能也更灵活。

数组的每个元素可以通过索引下标来访问,索引下标的范围是从 0 开始到数组长度减 1 的位置。内置的 len 函数将返回数组中元素的个数。

var a [3]int             // array of 3 integersfmt.Println(a[0])        // print the first elementfmt.Println(a[len(a)-1]) // print the last element, a[2]

默认情况下,数组的每个元素都被初始化为元素类型对应的零值,对于数字类型来说就是 0。

var q [3]int = [3]int{1, 2, 3}var r [3]int = [3]int{1, 2}fmt.Println(r[2]) // "0"

如果在数组的长度位置出现的是"..."省略号,则表示数组的长度是根据初始化值的个数来计算。因此,上面 q 数组的定义可以简化为:

q := [...]int{1, 2, 3}fmt.Printf("%T", q) // "[3]int"

数组的长度是数组类型的一个组成部分,因此[3]int 和[4]int 是两种不同的数组类型。

数组的长度必须是常量表达式,因为数组的长度需要在编译阶段确定。

q := [3]int{1, 2, 3}q = [4]int{1, 2, 3, 4} // compile error: cannot assign [4]int to [3]int

如果一个数组的元素类型是可以相互比较的,那么数组类型也是可以相互比较的,这时候我们可以直接通过==比较运算符来比较两个数组,只有当两个数组的所有元素都是相等的时候数组才是相等的。不相等比较运算符!=遵循同样的规则。

a := [2]int{1, 2}b := [...]int{1, 2}c := [2]int{1, 3}fmt.Println(a == b, a == c, b == c) // "true false false"d := [3]int{1, 2}fmt.Println(a == d) // compile error: cannot compare [2]int == [3]int

2. 切片(Slice)

Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个 slice 类型一般写作[]T,其中 T 代表 slice 中元素的类型;slice 的语法和数组很像,只是没有固定长度而已。

一个 slice 是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,而且 slice 的底层确实引用一个数组对象。

一个 slice 由三个部分构成:指针、长度和容量。

  • 指针指向第一个 slice 元素对应的底层数组元素的地址,要注意的是 slice 的第一个元素并不一定就是数组的第一个元素。

  • 长度对应 slice 中元素的数目;

  • 长度不能超过容量,容量一般是从 slice 的开始位置到底层数据的结尾位置。内置的 len 和 cap 函数分别返回 slice 的长度和容量。

表示一年中每个月份名字的字符串数组,还有重叠引用了该数组的两个 slice。数组这样定义:

months := [...]string{1: "January", /* ... */, 12: "December"}

因此一月份是 months[1],十二月份是 months[12]。

通常,数组的第一个元素从索引 0 开始,但是月份一般是从 1 开始的,因此我们声明数组时直接跳过第 0 个元素,第 0 个元素会被自动初始化为空字符串。

slice 的切片操作 s[i:j],其中 0 ≤ i≤ j≤ cap(s),用于创建一个新的 slice,引用 s 的从第 i 个元素开始到第 j-1 个元素的子序列。新的 slice 将只有 j-i 个元素。如果 i 位置的索引被省略的话将使用 0 代替,如果 j 位置的索引被省略的话将使用 len(s)代替。因此,months[1:13]切片操作将引用全部有效的月份,和 months[1:]操作等价;months[:]切片操作则是引用整个数组。让我们分别定义表示第二季度和北方夏天月份的 slice,它们有重叠部分:

Q2 := months[4:7]summer := months[6:9]fmt.Println(Q2)     // ["April" "May" "June"]fmt.Println(summer) // ["June" "July" "August"]

两个 slice 都包含了六月份。

append 函数

append 函数用于向 slice 追加元素:

var runes []runefor _, r := range "Hello, 世界" {    runes = append(runes, r)}fmt.Printf("%q", runes) // "["H" "e" "l" "l" "o" "," " " "世" "界"]"

为了提高内存使用效率,新分配的数组一般略大于保存 x 和 y 所需要的最低大小。通过在每次扩展数组时直接将长度翻倍从而避免了多次内存分配,也确保了添加单个元素操作的平均时间是一个常数时间。这个程序演示了效果:

func main() {    var x, y []int    for i := 0; i < 10; i++ {        y = appendInt(x, i)        fmt.Printf("%d cap=%d %v", i, cap(y), y)        x = y    }}//每一次容量的变化都会导致重新分配内存和copy操作:0  cap=1    [0]1  cap=2    [0 1]2  cap=4    [0 1 2]3  cap=4    [0 1 2 3]4  cap=8    [0 1 2 3 4]5  cap=8    [0 1 2 3 4 5]6  cap=8    [0 1 2 3 4 5 6]7  cap=8    [0 1 2 3 4 5 6 7]8  cap=16   [0 1 2 3 4 5 6 7 8]9  cap=16   [0 1 2 3 4 5 6 7 8 9]

让我们仔细查看 i=3 次的迭代。当时 x 包含了[0 1 2]三个元素,但是容量是 4,因此可以简单将新的元素添加到末尾,不需要新的内存分配。然后新的 y 的长度和容量都是 4,并且和 x 引用着相同的底层数组,如图 4.2 所示。

在下一次迭代时 i=4,现在没有新的空余的空间了,因此 appendInt 函数分配一个容量为 8 的底层数组,将 x 的 4 个元素[0 1 2 3]复制到新空间的开头,然后添加新的元素 i,新元素的值是 4。新的 y 的长度是 5,容量是 8;后面有 3 个空闲的位置,三次迭代都不需要分配新的空间。当前迭代中,y 和 x 是对应不同底层数组的 view。这次操作如图 4.3 所示。

内置的 append 函数可能使用比 appendInt 更复杂的内存扩展策略。

因此,通常我们并不知道 append 调用是否导致了内存的重新分配,因此我们也不能确认新的 slice 和原始的 slice 是否引用的是相同的底层数组空间。

同样,我们不能确认在原先的 slice 上的操作是否会影响到新的 slice。

关于"Go语言中的数组和切片实例分析"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Go语言中的数组和切片实例分析"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

数组 元素 长度 类型 容量 位置 分配 内存 函数 序列 底层 语言 月份 索引 实例 实例分析 分析 两个 空间 迭代 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 新华互联网科技 互联网科技公司起名 科技赋能下的互联网金融 涨乐互联网科技 互联网 科技 广州互联网科技公司 电子科技大学互联网 广州紫鲸互联网科技 人人互联网科技是培训 深圳卡尔迅互联网科技有限公司怎么样 海南购全球互联网科技 互联网巨头投资的硬核科技 互联网公司会议桌创意科技软装饰 广州慧亚互联网科技怎么样 和信科技工业互联网 移动互联网年度科技创新 洛阳昕诺飞互联网科技有限公司 互联网科技大奖都有哪些公司 无锡工业互联网科技有限公司 中国科技和美国互联网 上海挚品互联网科技有限公司 伟宏互联网科技 互联网科技会 甘肃拓世互联网科技有限公司 互联网科技博主是什么意思 哈尔滨屹滨互联网科技有限公司 开一家科技互联网公司需要多少钱 互联网科技新闻 张家口科技产业互联网平台 马化腾互联网科技教学
0