GO 语言学习(二)

复合数据类型 · 速记

四张图,记住数组 / 切片 / Map / 结构体最关键的差异
6 分钟速览 🧩 4 种类型 ⚠️ 3 大陷阱 3 道自测
📏
数组
固定长度
连续内存块
值类型
🔗
切片
动态视图
共享底层数组
引用语义
🗺️
Map
哈希表
无序键值对
引用类型
🧱
结构体
字段聚合
自定义建模
值类型
01
数组 Array
📏长度是类型的一部分
[3]int[4]int
不可互赋 / 比较 / 作同型参数。
💾值类型
赋值与传参 = 整体拷贝
函数内改副本不影响原数组。
💥越界即 panic
下标限定 0 ~ len-1
超范围运行时崩溃。
补零值(int=0 / string="" / bool=false)· 同长同型才可 == · [...]int{1,2,3} 推断长度 · [5]int{2:100} 下标赋值
💡 常见疑问:数组与切片声明差在哪?
数组定长、值类型、长度属类型;切片动态、引用、共享底层数组。声明:var a [3]int(零值数组)/ var s []int(nil 切片)/ s := []int{}(空切片)/ make([]int,3,5)(指定 len·cap)。
02
切片 Slice
切片头(24B)
ptr
len
cap
底层数组
0
1
2
3
4
切片头只存指针 / 长度 / 容量,数据在底层数组。由同一数组切出的子切片共享该数组。
s (len 3)
ptr
len 3
cap 5
sub := s[:2] (len 2)
ptr
len 2
cap 5
⚠ 两者 ptr 指向同一底层数组sub[0]=9 时,s 也变成 [9 2 3]
引用语义:只存头,不存数据append:容量够原地写,不够才扩容copy:深拷贝,断绝共享
💡 常见疑问:为什么 int 后面要加 {}
[]int 只是类型名;加 {} 才是复合字面量——当场造出值。空 {} = 创建但无元素。数组 / Map / 结构体同理。
💡 常见疑问:切片类型只能是 []int 吗?
切片类型 = [] + 元素类型[]int/[]string/[]float64 互不相同。长度不参与类型——这是与数组最大区别。

nil 切片 · var s []int

s == nil ✓
底层数组
JSON 序列化null
可读 / append

空切片 · s := []int{}

s == nil ✗
底层数组有(空)
JSON 序列化[]
可读 / append
要点:两者均可读、可 append、可 range;差异仅在 ==nil 判断与 JSON 输出。下标写入二者都越界 panic——「不可写」形容的是 nil map,非切片。
03
映射 Map
哈希表引用类型无序:遍历顺序随机delete / len
nil map 写入即 panic:须先 make 或字面量初始化,否则 m[k]=v 崩溃。
v := m[k]
不存在也返回零值
v, ok := m[k]
ok = truekey 真实存在,v 即其值(含零值情形)
ok = falsekey 不存在,v 是零值兜底
通用惯用法 value, ok := 亦见于类型断言 i.(T) 与 channel 接收 <-ch
04
结构体 Struct
💾
值类型
赋值 / 传参整体拷贝;大结构体建议传 *T
⚖️
可比较有条件
所有字段可比时才能 ==;含 slice / map 字段则不可比。
🧩
嵌入组合
匿名嵌套自动提升字段与方法,实现「组合优于继承」。
🏷️
tag 元信息
`json:"name"` 供反射 / 序列化读取,不影响运行时。
!
三大高频陷阱
💾
数组传参被拷
现象:函数内改不动原数组。
根因:值类型整体拷贝
规避:传 *[N]T 或改用切片。
🔗
切片共享污染
现象:改子切片连累原切片。
根因:共享底层数组
规避:独立时用 copy 或触发扩容。
🗺️
nil map 写入
现象:panic
根因:未初始化
规避:先 make 或字面量。

四类型对比速查

维度数组切片Map结构体
语义值类型引用引用值类型
长度固定·属类型动态动态字段固定
可比 ==同长同型仅 nil仅 nil字段全可比
零值全零数组nilnil字段全零
传参开销整体(大)仅头仅头整体(大→指针)
日常定位少用最常用KV 查询建模实体

自测 3 题

Q1
var a [3]int
var b [4]int
a = b 能编译?
查看解析
不能。长度不同即类型不同,Go 禁止跨类型赋值。
Q2
a:=[]int{1,2,3}
b:=a[:2]
b[0]=9
a 变成?
查看解析
[9 2 3]。b 与 a 共享底层数组,改 b[0] 即改底层元素。
Q3
var m map[int]int
m[1]=10 会?
查看解析
panic(向 nil map 写入)。修复:make 或字面量初始化。