基础语法 —— 数组和切片 【相关阅读】
数组和别的语言的数组差不多,语法是:[cap]type
- 初始化要指定长度(或者叫做容量),一旦定义了长度后将不可修改长度
- 可以直接初始化数组,不设置数值将填入数据类型默认值
- arr[i]的形式访问元素
- len 和 cap 操作用于获取数组长度
- 数组的len 和 cap 结果是一样的,就是数组的长度
- 定义数组的时候,数组的长度可以省略(填写方式 array:=[...]string{"a","b","c","d","e"} ),golang会根据数据长度来自动判断数据长度。但只有特定索引元素赋值的数据就不适合此方法,如(array1:=[5]string{1:"b",3:"d"})

切片,语法:[]type 【切片相关阅读】
- 同数组一样,可以直接初始化,不设置数值将填入数据类型默认值
- make初始化:make([]type, length, capacity),make可以理解为创建一个指定容量的桶
- arr[i] 的形式访问元素
- append 追加一个、多个元素或追加另外一个切片

- len 获取元素数量
- cap 获取切片容容量
- 推荐写法:s1 := make([]type, 0, capacity),【make相关阅读】

数组与切片的使用选择:
当你明确知道数据长度时,你可以使用数组。
当不确定元素长度时,并且需要随时可能进行追加元素的操作时使用切片,但长度尽量开始就预估好,避免重复申请扩容浪费内存

子切片:数组和切片都可以通过[start:end] 的形式来获取子切片
- arr[start:end],获得[start, end)之间的元素
- arr[:end],获得[0, end) 之间的元素,array[:4] 等价于 array[0:4]
- arr[start:],获得[start, len(arr))之间的元素,array[1:] 等价于 array[1:5]
- 前后都不写时返回全部数据,array[:] 等价于 array[0:5],等于array

最直观的对比:ArrayList,即基于数组的 List 的实现,切片的底层也是数组跟 ArrayList 的区别:
- 切片操作是有限的,不支持随机增删(即没有 add, delete 方法,需要自己写代码)
- 只有 append 操作
- 子切片操作,和原本切片是共享底层数组(意思是你改了原始切片数据,子切片也会被修改)

Map(映射-可以理解为PHP的键值数组)
在 Go 语言中,map 是一个无序的 K-V 键值对集合,结构为 map[K]V。其中 K 对应 Key,V 对应 Value。map 中所有的 Key 必须具有相同的类型,Value 也同样,但 Key 和 Value 的类型可以不同。此外,Key 的类型必须支持 == 比较运算符,这样才可以判断它是否存在,并保证 Key 的唯一。
// 创建一个 map 可以通过内置的 make 函数
nameAgeMap:=make(map[string]int)
// 添加了一个键值对,Key 为飞雪无情,Value 为 20
nameAgeMap["飞雪无情"] = 20
// 也可在初始化时直接填入数据,如下:
nameAgeMap:=map[string]int{"飞雪无情":20}
Map 获取和删除:map 的操作和切片、数组差不多,都是通过 [] 操作符,只不过数组切片的 [] 中是索引,而 map 的 [] 中是 Key
//添加键值对或者更新对应 Key 的 Value
nameAgeMap["飞雪无情"] = 20
//获取指定 Key 对应的 Value
age:=nameAgeMap["飞雪无情"]
map 的 [] 操作符可以返回两个值:
-
第一个值是对应的 Value;
-
第二个值标记该 Key 是否存在,如果存在,它的值为 true。
nameAgeMap := make(map[string]int)
nameAgeMap["飞雪无情"] = 20
age, ok := nameAgeMap["飞雪无情1"]
//ok为判断值
if ok {
fmt.Println(age)
}
要删除 map 中的键值对,使用内置的 delete 函数即可
delete(nameAgeMap,"飞雪无情")
delete 有两个参数:第一个参数是 map,第二个参数是要删除键值对的 Key。
遍历 Map:map 的遍历使用 for range 循环。需要注意的是 map 的遍历是无序的,也就是说你每次遍历,键值对的顺序可能会不一样。如果想按顺序遍历,可以先获取所有的 Key,并对 Key 排序,然后根据排序好的 Key 获取对应的 Value。
//测试 for range
nameAgeMap["飞雪无情"] = 20
nameAgeMap["飞雪无情1"] = 21
nameAgeMap["飞雪无情2"] = 22
for k,v:=range nameAgeMap{
fmt.Println("Key is",k,",Value is",v)
}
Map 的大小:和数组切片不一样,map 是没有容量的,它只有长度,也就是 map 的大小(键值对的个数)。
fmt.Println(len(nameAgeMap))