type
status
date
slug
summary
tags
category
icon
password
AI summary

Go语言基础之切片


1. 什么是切片

切片(Slice)是 Go 语言中一种比数组更强大的数据结构,提供了对数组的一个动态视图。切片拥有可变长度的特点,更适合处理需要灵活大小的数据集合。
切片的本质是对底层数组的一个描述和引用,因此切片:
  1. 是引用类型。
  1. 可以动态调整长度。
  1. 包含三部分:指向底层数组的指针、切片的长度(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 语言中对底层数组的一种抽象,其本质是一个 描述符,包含了以下三部分:
  1. 指针(Pointer):指向底层数组中切片起始位置的指针。
  1. 长度(Length):当前切片包含的元素个数。
  1. 容量(Capacity):从切片起始位置到底层数组末尾的最大元素数。
因此,切片并不直接存储数据,而是通过指针引用底层数组。修改切片中的值实际上是对底层数组的操作。

切片的内存布局

切片在内存中的布局如下图所示:
假设以下代码:
切片 slice 的内容:
  • 指针:指向数组的第二个元素(20)。
  • 长度:3(20, 30, 40)。
  • 容量:4(从 20 开始,到数组末尾 50 的元素个数)。
示意图

切片的共享特性

切片与底层数组共享数据,当多个切片引用同一个底层数组时,一个切片的修改会影响其他切片。
示例代码:
示意图:

切片的扩容机制

当使用 append 向切片添加元素时,如果容量不足,Go 会创建一个新的底层数组,将原切片的数据复制过去,然后追加新元素。
扩容规则
  1. 如果当前容量小于 1024,则新容量为原容量的两倍。
  1. 如果当前容量大于等于 1024,则新容量增加为原容量的 1.25 倍。
示例代码:
扩容前后示意图:

5. 注意事项

  1. 切片是引用类型,直接赋值切片会复制引用,而不是复制数据。
  1. 如果切片在追加元素时容量不足,Go 会创建一个新的底层数组并拷贝数据,因此原始切片不会受到影响。
  1. 切片操作时要注意索引越界问题。

6. 总结

  • 切片是动态数组的抽象,支持灵活的长度调整。
  • 切片的操作包括访问、遍历、追加和拷贝。
  • 切片底层依赖数组,实现了高效的共享和扩展机制。
  • 切片比数组更常用,几乎是 Go 开发中不可或缺的数据结构。
 
Map数组