Go语言切片如何创建_Golang slice声明与使用方法

8次阅读

go切片必须基于数组或已有切片创建,常用make(控制长度/容量)或字面量(初始化已知元素);支持截取生成共享底层数组的视图;需警惕nil/空切片差异、append扩容机制及底层数组生命周期问题。

Go语言切片如何创建_Golang slice声明与使用方法

Go语言中切片不能直接“创建”而必须基于底层数组(或已有切片)生成,最安全、最常用的方式是用 make 或字面量初始化。

make 创建带长度和容量的切片

这是控制内存分配最明确的方式,适用于需要预分配空间、避免频繁扩容的场景(比如批量读取文件、网络缓冲)。

  • make([]T, len):创建长度为 len、容量也为 len 的切片,所有元素为零值
  • make([]T, len, cap):创建长度 len、容量 capcap >= len)的切片,超出 len 的部分不可访问但可被 append 复用
  • 如果 len > cap,编译报错:len larger than cap in make([]T)
  • 容量影响 append 性能:只要不超容,append 是 O(1);一旦触发扩容(通常翻倍),会分配新底层数组并拷贝,开销变大

示例:

buf := make([]byte, 0, 1024) // 预留1KB容量,初始长度0,适合循环append

用字面量声明并初始化切片

适合已知初始元素的场景,简洁直观,底层自动调用 make 并赋值。

立即学习go语言免费学习笔记(深入)”;

  • []int{1, 2, 3}:长度和容量都为 3
  • []String{"a", "b"}:类型由元素推导,无需显式写 []string(但在函数参数或变量声明中常需)
  • 空切片字面量 []int{}var s []int 效果一致:长度 0、容量 0、底层数组为 nil
  • 注意:[3]int{1,2,3} 是数组,不是切片;少一个 [] 就完全不是同一类型

从数组或已有切片截取生成新切片

这是切片“视图”特性的核心用法,不分配新底层数组(除非后续 append 触发扩容),共享内存。

  • arr[1:3]:从数组 arr 截取,新切片长度 = 3-1,容量 = len(arr)-1
  • s[2:4:6]:三索引切片,显式指定新容量(上限为原容量减起始偏移),防止意外覆盖原数据
  • 越界 panic:索引超出原切片/数组范围(如 s[10:]len(s)==5)会 panic,运行时检查
  • 修改新切片元素会反映到原底层数组——这是共享语义,也是常见 bug 来源(比如函数返回局部数组的切片,但数组上已失效)

常见误用与坑

很多问题源于混淆“零值切片”“nil 切片”和“空切片”,以及对底层数组生命周期的误判。

  • var s []ints = nils = []int{} 三者 len/cap 都是 0,但前两者 s == nil 为 true,最后一个为 false;json.Marshalnil 切片输出 NULL,对空切片输出 []
  • 在循环中反复 append 到同一个切片,却未重置(如 s = s[:0]),会导致旧数据残留
  • 函数接收 []T 参数时,内部 append 可能扩容并返回新底层数组,但调用方变量未更新——必须显式接收返回值:s = append(s, x)
  • range 遍历切片时,迭代变量是副本,修改它不影响原切片;要改元素得用索引:s[i] = ...

底层数组的生命周期只取决于是否有活跃的切片引用它——哪怕原始变量早已离开作用域,只要还有切片指向它,就不会被回收。这点和 C 的指针不同,也和 java 的引用不同,容易在长期运行服务中引发意料外的内存驻留。

text=ZqhQzanResources