内容目录
概述
go提供了以下三类集合:
- 数组(Arrays)
- 切片(Slices)(动态数组)
- Map
- Set不是Go提供的集合,可以使用Map来实现Set(Java也是通过Map实现的Set)
数组(Arrays)
数组的长度是固定的,定义完成后是无法改变长度的。下面看一下数组的定义:
var array [5]int
上面代码定义了一个5个元素的数组,go中数组不像Java中定义后要new,go默认就已经分配了空间,并把元素设置了零值。比如:我现在循环打印这个数组就,我们就会知道每个元素都是0:
for i := 0; i< len(array); i++ {
fmt.Println(arr[i])
}
数组元素初始值
那其他类型的数组的初始值是什么?go中有很多类型,我们来给一个列表:
- 数值类型(如int, float等):0
- 布尔类型:false
- 字符串类型:"" (空字符串)
- 指针:nil
- 接口(interface):nil
- 切片(slice):nil
- 映射(map):nil
- 函数:nil
- 通道(channel):nil
- 结构体(struct):所有字段都是其对应数据类型的零值
数组操作
增
array := [5]int{1, 2, 3, 4, 5}
删
不能删除。
查
// 基于索引查值
value := array[2]
// 查询数组长度
len(array)
// 遍历for循环
for i := 0; i < len(array); i++ {
value := array[i]
}
// 遍历range
for i, value := range array {
println("index: %d, value: %d", i, value)
}
改
// 修改第二个元素
array[1] = 10
关于数组的增,查和改操作大家可以去搜搜工具类。
切片(Slices)(动态数组)
切片就是一个数组,可以根据情况进行扩缩容(类似于Java ArrayList)。切片底层就是一个数组。
操作
增
创建一个切片,和数组方式差不多:[]int
,在[]中不指定长度就好了;指定了就是数组了。
// 创建并初始化
slice := []int{1, 2, 3, 4, 5}
// 创建一个空的
slice := make([]int, 5)
添加元素需要使用append
函数
slice = append(slice, 6)
删
切片支持删除,删除也是使用append,但是也可以通过创建新切片来完成
// 创建一个新slice,不包含第一个元素
slice1 := slice[1:]
// 删除第一个元素
slice = append(slice[1:])
for i, value := range slice1 {
println("index: %d, value: %d", i, value)
}
// 删除第二个元素:2
slice = append(slice[:1], slice[2:]...)
for i, value := range slice {
fmt.Printf("index: %d, value: %d\n", i, value)
}
// 删除第二和第三个元素:2,3,
slice = append(slice[:1], slice[3:]...)
for i, value := range slice {
fmt.Printf("index: %d, value: %d\n", i, value)
}
删除多个就是更改你的删除范围(数组索引值)就好了,但是你的索引超过了数组的最大索引范围就要报错了,就是数组越界。
删除中间一个元素:
删除多个元素:
数组越界:
查
读取切片的元素和数组是一样的。
value := slice[2]
改
修改切片是和数组一样的。
slice[1] = 10
切片和数组的区别
下面是一个展示数组 (Array) 和切片 (Slice) 在 Go 语言中的主要区别的表格:
特性 | 数组 (Array) | 切片 (Slice) |
---|---|---|
长度 | 长度固定,创建时就要指定大小 | 长度可以动态变化,可以在运行时添加和删除元素 |
动态性 | 静态的 | 动态的 |
内存占用 | 较小 | 大小在运行时可能会改变 |
定义方式 | var arr [n]T | var slice []T |
创建方式 | arr := [n]T{t1, t2, t3, …} | slice := []T{t1, t2, t3, …} 或slice := make([]T, len, cap) |
初始值 | 取决于数组元素类型 | nil |
Map
Map就是键值对咯,像Java中的HashMap,python的字典之类的。
go中的这个map不是协程安全的,如果想要使用协程安全的,可以使用sync包中的map。
操作
增
map使用make函数来创建或者直接初始化键值对创建。
make函数基本啥都能造。
// 创建一个空的map
m := make(map[string]int)
// 创建并初始化
m := map[string]int{
"1": 1,
"2": 2,
}
// 添加键值对
m["3"] = 3
删
删除用delete函数,第一参数是map,第二个参数是key。
delete(m, "1")
查
// 判断是否存在
value, exists := m["2"]
if exists {
fmt.Println(value)
} else {
fmt.Println("key不存在.")
}
// 遍历
for key, value := range m {
fmt.Printf("key: %s, values: %d.", key, value)
}
改
修改map的数组和python的字典类似:
m["1"] = 10
Set
Set go中并没有直接提供,我们使用map就可以很快的造一个Set。
type Set struct {
elements map[interface{}]bool
}
func NewSet() *Set {
return &Set{
elements: make(map[interface{}]bool),
}
}
// Add元素到set.
func (set *Set) Add(element interface{}) {
set.elements[element] = true
}
// Remove元素从set.
func (set *Set) Remove(element interface{}) {
delete(set.elements, element)
}
// Exists检查元素是否在set中.
func (set *Set) Exists(element interface{}) bool {
_, exists := set.elements[element]
return exists
}
//读取所有元素
func (set *Set) Elements() []interface{} {
keys := make([]interface{}, len(set.elements))
i := 0
for key := range set.elements {
keys[i] = key
i++
}
return keys
}