Golang 从入门到放弃 -0x07
数组、切片、map 的常见写法,以及切片共享底层数组这类高频坑。
这一章要讲三个高频选手:数组、切片、map。名字看着都认识,但第一次写的时候,尤其是切片,很多人都会有一种“这不是数组吗,怎么又不太像”的迷惑感。
数组:长度写死的老实人
Go 的数组长度是类型的一部分,这句话很重要。[3]int 和 [4]int 不是同一个类型。
var nums [3]int
nums[0] = 10
nums[1] = 20
nums[2] = 30
fmt.Println(nums)也可以直接初始化。
names := [3]string{"Go", "Python", "Java"}
fmt.Println(len(names))不过说实话,数组在 Go 日常业务里存在感没有那么强。大部分时候,你真正天天打交道的是切片。
切片:真正常用的动态序列
切片可以理解成“对数组的一层更灵活的包装”。它不直接把数据全背在身上,而是描述一段连续的数据区域。
nums := []int{1, 2, 3}
fmt.Println(nums)
fmt.Println(len(nums), cap(nums))追加元素用 append。
nums = append(nums, 4)
nums = append(nums, 5, 6)
fmt.Println(nums)切片也可以从数组或者另一个切片里切出来。
arr := [5]int{10, 20, 30, 40, 50}
part := arr[1:4]
fmt.Println(part) // [20 30 40]区间规则还是老朋友:左闭右开。
切片最容易踩的坑:共享底层数组
这是切片最值得早点知道的一件事。你以为你切出来的是副本,实际上很多时候只是同一块底层数据的不同窗口。
nums := []int{1, 2, 3, 4}
part := nums[1:3]
part[0] = 200
fmt.Println(nums) // [1 200 3 4]
fmt.Println(part) // [200 3]如果你明确需要一份独立副本,就别偷懒,老老实实复制。
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)
dst[0] = 999
fmt.Println(src) // [1 2 3]
fmt.Println(dst) // [999 2 3]make 是干嘛的
切片、map、channel 这几位,一般都喜欢用 make 创建。
scores := make([]int, 3, 5)
fmt.Println(scores) // [0 0 0]
fmt.Println(len(scores)) // 3
fmt.Println(cap(scores)) // 5这里长度是 3,容量是 5。容量可以先理解成“当前底层空间够你再塞几个”的意思,够用阶段知道这个就行,别一开始就和扩容算法死磕。
map:键值对老熟人
map 就是字典、哈希表、对象那一类亲戚,拿来存键值对最顺手。
ages := map[string]int{
"raymond": 18,
"tom": 20,
}
fmt.Println(ages["raymond"])也可以先用 make 创建,再慢慢塞。
userAge := make(map[string]int)
userAge["alice"] = 21
userAge["bob"] = 22取 map 的值时有个很经典的双返回值写法,用来判断 key 到底存不存在。
age, ok := userAge["jack"]
if ok {
fmt.Println("年龄是", age)
} else {
fmt.Println("查无此人")
}删除元素用 delete。
delete(userAge, "alice")遍历
数组、切片、map 都可以配合 range 来遍历。
nums := []int{10, 20, 30}
for index, value := range nums {
fmt.Println(index, value)
}
for key, value := range userAge {
fmt.Println(key, value)
}如果你不需要索引或者 key,可以用下划线占位。
for _, value := range nums {
fmt.Println(value)
}小结
如果只记一句话,那就是:
- 数组长度固定,切片才是日常主力。
- 切片很方便,但它可能共享底层数据。
- map 用起来很爽,但取值时记得考虑 key 不存在的情况。
下一章开始讲 struct。也就是 Go 里“虽然我没有 class,但我照样能组织数据”的那一套。