type
status
date
slug
summary
tags
category
icon
password
AI summary
Go语言基础之切片
1. 什么是切片
切片(Slice)是 Go 语言中一种比数组更强大的数据结构,提供了对数组的一个动态视图。切片拥有可变长度的特点,更适合处理需要灵活大小的数据集合。
切片的本质是对底层数组的一个描述和引用,因此切片:
- 是引用类型。
- 可以动态调整长度。
- 包含三部分:指向底层数组的指针、切片的长度(len)和容量(cap)。
2. 声明和初始化切片
2.1 声明切片
切片的声明语法:
[]
表示切片类型。
Type
是切片中元素的类型。
示例代码:
2.2 初始化切片
初始化方式1:从数组生成切片
通过数组的切片操作符
[:]
从数组中生成切片。注意:切片的范围是
[start:end)
,不包括 end
位置的元素。示例代码:
初始化方式2:使用 make
函数
通过
make
函数创建切片:length
是切片的初始长度。
capacity
是切片的容量(可选)。如果省略,容量等于长度。
示例代码:
初始化方式3:直接赋值
示例代码:
3. 切片的操作
3.1 访问切片元素
切片元素可以通过索引访问,与数组的访问方式一致。
示例代码:
3.2 切片的遍历
切片的遍历与数组类似,可以使用
for
循环或 for range
。示例代码:
3.3 切片的扩容与追加
使用内置的
append
函数可以向切片追加元素,当容量不足时,切片会自动扩容。语法:
示例代码:
3.4 切片的拷贝
使用内置的
copy
函数可以将一个切片的内容拷贝到另一个切片。语法:
destSlice
是目标切片,srcSlice
是源切片。
- 拷贝的元素数是两者最小长度的值。
示例代码:
4. 切片的底层原理
切片的本质
切片(Slice)是 Go 语言中对底层数组的一种抽象,其本质是一个 描述符,包含了以下三部分:
- 指针(Pointer):指向底层数组中切片起始位置的指针。
- 长度(Length):当前切片包含的元素个数。
- 容量(Capacity):从切片起始位置到底层数组末尾的最大元素数。
因此,切片并不直接存储数据,而是通过指针引用底层数组。修改切片中的值实际上是对底层数组的操作。
切片的内存布局
切片在内存中的布局如下图所示:
假设以下代码:
切片
slice
的内容:- 指针:指向数组的第二个元素(
20
)。
- 长度:3(
20, 30, 40
)。
- 容量:4(从
20
开始,到数组末尾50
的元素个数)。
示意图:
切片的共享特性
切片与底层数组共享数据,当多个切片引用同一个底层数组时,一个切片的修改会影响其他切片。
示例代码:
示意图:
切片的扩容机制
当使用
append
向切片添加元素时,如果容量不足,Go 会创建一个新的底层数组,将原切片的数据复制过去,然后追加新元素。扩容规则:
- 如果当前容量小于 1024,则新容量为原容量的两倍。
- 如果当前容量大于等于 1024,则新容量增加为原容量的 1.25 倍。
示例代码:
扩容前后示意图:
5. 注意事项
- 切片是引用类型,直接赋值切片会复制引用,而不是复制数据。
- 如果切片在追加元素时容量不足,Go 会创建一个新的底层数组并拷贝数据,因此原始切片不会受到影响。
- 切片操作时要注意索引越界问题。
6. 总结
- 切片是动态数组的抽象,支持灵活的长度调整。
- 切片的操作包括访问、遍历、追加和拷贝。
- 切片底层依赖数组,实现了高效的共享和扩展机制。
- 切片比数组更常用,几乎是 Go 开发中不可或缺的数据结构。
- 作者:IT小舟
- 链接:https://www.codezhou.top/article/%E5%88%87%E7%89%87
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。