数组 & 切片
数组
具有相同 唯一类型 的一组以编号且长度固定的数据项序列
可以是任意的原始类型例如整型、字符串或者自定义类型
长度必须是一个常量表达式,并且必须是一个非负整数
数组长度也是数组类型的一部分
数组长度最大为 2Gb
把一个大数组传递给函数会消耗很多内存。有两种方法可以避免这种现象:
- 传递数组的指针
- 使用数组的切片
数组是值类型
切片
切片是一个 长度可变的数组
对于 切片 s 来说不等式0 <= len(s) <= cap(s)
永远成立
多个切片如果表示同一个数组的片段,它们可以共享数据;因此一个切片和相关数组的其他切片是共享存储的
切片是引用类型
切片在未初始化之前默认为 nil,长度为 0
注意 绝对不要用指针指向 slice。切片本身已经是一个引用类型,所以它本身就是一个指针!!
字符串与切片的内存结构
字符串 string s = "hello"
和子字符串 t = s[2:3]
在内存中的结构可以用下图表示:
Go 语言中的字符串是不可变的
可以通过将字符串转换为切片来实现修改字符串
Map
未初始化的 map 的值是 nil
key 可以是任意可以用 ==
或者!=
操作符比较的类型,比如 string、int、float
- 含有数组切片的结构体不能作为 key,只包含内建类型的 struct 是可以作为 key 的
若要用结构体作为 key 可以提供Key()
和Hash()
方法 – 类似于 equals 和 hashCode 方法 - 指针和接口类型可以作为 key
效率:array[index] | slice[index] >> map[key];map-key查询效率很高,但仍远低于array[index]
val := map[key]
,如果 key 不存在,则 val 为值类型的空值
不要使用 new,永远用 make 来构造 map
出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明
map 中是否存在 key:val, isPresent = map[key]
从 map 中删除 key:delete(map, key)
(即使 key 不存在,也不会报错)
遍历:
for key, val := range map1 {
// todo
}
// 只获取 key
for key := range map1 {
// todo
}
map 类型切片:必须使用两次 make 实现。① 分配切片;② 分配切片中每个 map 元素
items := make([]map[int]int, 5)
for i := range items {
items[i] = make(map[int]int, 1)
items[i][1] = 2
}
map 排序:将 key 拷贝到切片,对切片进行排序