外观
数组、切片与字符串
- 状态:未准备
- 适用方向:Go 全栈 / Go 后端
- 最近复习:待填写
- 下次复习:待安排
一句话回答
数组长度属于类型,切片是底层数组的一段视图,字符串是不可变字节序列;切片共享、append 分配与 UTF-8 边界是高频考点。
原理解释
切片可理解为底层数组引用、长度和容量。赋值复制切片描述信息;append 容量够时复用数组,不够时分配并复制,必须接住返回值。增长策略属于实现,不背“永远翻倍”。
go
a := []int{1, 2, 3}
b := a[:2]
b = append(b, 9) // a == [1 2 9],复用底层数组。
c := a[:2:2]
c = append(c, 8) // a 仍为 [1 2 9],本次 append 分配新数组。copy 复制元素,数量为两边长度较小者,支持重叠;元素含指针时仍是浅拷贝。nil 与空切片 len 都为 0、都可 append,但 nil 判断与 JSON 表达可能不同。
len("你好") 为 6,len([]rune("你好")) 为 2。字符串索引得到 byte,range 解码 rune 并返回字节偏移。rune 是码点,不一定是用户感知的完整字符;字符串也能包含无效 UTF-8。
场景与边界
小切片长期引用大数组可能保留整块内存,可按需复制。异步消费者尚未完成时复用缓冲区,会读到被覆盖的数据。共享数组写入仍需同步。
项目中的应用
对照 SimulSpeak 媒体管线,检查音频缓冲区所有权;字幕按字节截断可能破坏 UTF-8。
常见追问
- append 后原切片会变吗? 长度不会自动变,共享的底层内容可能变;扩容后可能分离。
- 切片能作 map key 吗? 不能;元素可比较的数组可以。
- string 转 []byte 一定零拷贝吗? 不应依赖;按语言语义保证独立修改安全,优化交给编译器。