模块 4 · 第 2 课(共 5)课程中的17/50~15 min
模块课程(2/5)
切片:惯用结构
切片是 Go 中最常用的数据结构:动态视图
在底层数组上。语法:[]T。与数组不同的是,长度是
不是类型的一部分,您可以使用 append 来扩展它。
切片的解剖
切片内部是一个三字段结构:
- 指向底层数组中第一个元素的指针
- 长度 (
len):可见元素的数量 - 容量 (
cap):从视图开始可用的元素 到底层数组的末尾
Go
s := []int{10, 20, 30}
fmt.Println(len(s), cap(s)) // 3 3创建
Go
a := []int{1, 2, 3} // literal
b := make([]int, 3) // [0 0 0] len=3 cap=3
c := make([]int, 3, 10) // len=3 cap=10 (reserved)
var d []int // nil slice: len=0 cap=0, still usable with appendappend:始终分配结果
append 添加元素并返回一个新切片(可能
如果容量不足则分配新数组):
Go
s := []int{1, 2, 3}
s = append(s, 4) // [1 2 3 4]
s = append(s, 5, 6, 7) // append multiple elements
s = append(s, altra...) // concatenate another slice (spread)切片表达式 s[a:b]
提取从 a (包含)到 b (不包含)的子切片:
Go
s := []int{10, 20, 30, 40, 50}
sub := s[1:4] // [20 30 40]
inizio := s[:2] // [10 20]
fine := s[3:] // [40 50]
intera := s[:] // [10 20 30 40 50]子切片与原始切片共享底层数组:
通过 sub[i] = ... 的突变在 s 中也可见。
陷阱:数组共享
Go
s := []int{1, 2, 3, 4}
sub := s[0:2]
sub[0] = 99
fmt.Println(s) // [99 2 3 4] — modified!要获取独立副本,请使用 copy 或 append:
Go
out := make([]int, len(sub))
copy(out, sub)尝试一下
锻炼#go.m4.l2.e1
尝试:0加载中...
使用 [1, 2, 3] 创建一个切片 s 并使用append 添加 4。
正在加载编辑器...
显示提示
始终将追加的结果分配回“s”。
3 次尝试后可用的解决方案
锻炼#go.m4.l2.e2
尝试:0加载中...
使用切片表达式从索引 1(含)到 3(不含)提取元素(即 [20, 30])。
正在加载编辑器...
显示提示
语法:`s[start:end]`,包含`start`,不包含`end`。
3 次尝试后可用的解决方案
Quiz#go.m4.l2.e3
准备好以下哪个写法是错误的?
Go
s := []int{1, 2, 3}
// (a) s = append(s, 4)
// (b) append(s, 4)回顾
[]T:数组的动态视图;三重(ptr、len、cap)。make([]T, len, cap)进行预分配;var s []T用于可用的 nil 切片。s = append(s, ...):始终分配结果。s[a:b]共享底层数组:copy(...)用于独立副本。nil切片 = 可以读取/范围/追加;与 nil 地图完全不同。