一、Map概述
在Go语言中,map是一种无序的键值对集合,也被称为字典(Dictionary)或关联数组。map中的每个元素都由一个唯一的键和对应的值组成。通过键可以快速地访问或修改对应的值。
二、Map的定义
map的定义语法如下:
var mapName map[KeyType]ValueType
其中,mapName是map的名称,KeyType是键的类型,ValueType是值的类型。需要注意的是,map的key必须是可比较的类型,因为key是唯一的。引用类型(如切片、函数等)不能作为key。
三、Map的基本操作
- 创建和初始化
创建map时,可以使用make
函数来分配内存。如果未分配内存,则map的值为nil。
示例代码:
var m1 map[string]int // 定义一个map,未分配内存
fmt.Println(m1 == nil) // 输出:truem1 = make(map[string]int) // 分配内存
fmt.Println(m1 == nil) // 输出:falsem1["name"] = 1 // 赋值
fmt.Println(m1) // 输出:map[name:1]m2 := make(map[string]int, 10) // 定义map,并分配容量为10
fmt.Println(len(m2)) // 输出:0
m2["count"] = 8
fmt.Printf("%#v\n", m2) // 输出:map[string]int{"count":8}m3 := map[string]string{"phone": "xiaomi", "car": "Tesla"} // 直接定义并赋值
fmt.Println(m3) // 输出:map[car:Tesla phone:xiaomi]
- 删除元素
使用delete
函数可以删除map中的指定key。
示例代码:
m := map[string]string{"phone": "xiaomi", "car": "Tesla"}
fmt.Println(m) // 输出:map[car:Tesla phone:xiaomi]
delete(m, "car")
fmt.Println(m) // 输出:map[phone:xiaomi]
- 获取元素
获取map中的一个值时,可以接收两个值,第一个是value,第二个是一个判断是否存在key的布尔值。如果存在就是true,不存在就是false。
示例代码:
m := map[string]string{"phone": "xiaomi", "car": "Tesla"}
if val, ok := m["name"]; ok {fmt.Println("name", val)
} else if _, ok = m["car"]; ok {fmt.Println("car found")
} else {fmt.Println("not find key")
}
// 输出:car found
- 遍历map
使用for range
可以遍历map。需要注意的是,map的遍历是没有顺序的,而是随机的。这是因为map是一种哈希表(hash table)的实现,它使用哈希函数将键映射到桶(bucket),并在桶中存储键值对。哈希表在内部使用桶数组来存储键值对,而桶数组的顺序是不确定的。
示例:
m := map[string]string{"phone": "xiaomi", "car": "Tesla"}
for key, value := range m {fmt.Println(key, value)
}
// 输出(顺序可能是随机的):
// phone xiaomi
// car Tesla
如果需要按顺序遍历map,可以先将key按顺序存入切片中,然后对切片进行排序,再按顺序访问map中的值。
示例代码:
list := make([]string, 0)
m := map[string]string{"d": "dd", "c": "cc", "b": "bb", "a": "aa"}
for k := range m {list = append(list, k) // 将key添加到切片中
}
sort.Strings(list) // 对切片中的元素排序
for _, key := range list {fmt.Println(m[key]) // 按顺序打印
}
// 输出:
// aa
// bb
// cc
// dd
四、总结
map是Go语言中一种非常强大的数据结构,它允许我们通过键快速地访问或修改对应的值。在使用map时,需要注意key必须是可比较的类型,并且map的遍历顺序是随机的。如果需要按顺序遍历map,可以先将key存入切片中,然后对切片进行排序。
示例代码:
func TestMap(t *testing.T) {m := map[string]int{"a": 1, "b": 2}fmt.Println(m)var m1 map[string]int // 定义一个map,未分配内存fmt.Println(m1 == nil) // 输出:truem1 = make(map[string]int) // 分配内存fmt.Println(m1 == nil) // 输出:falsem1["name"] = 1fmt.Println(m1) //map[name:1]m2 := make(map[string]int, 10) // 定义map,并分配容量为10fmt.Println(len(m2)) // 输出:0m2["count"] = 8fmt.Printf("%#v\n", m2) // 输出:map[string]int{"count":8}m3 := map[string]string{"phone": "xiaomi", "car": "Tesla"} // 直接定义并赋值fmt.Println(m3) // 输出:map[car:Tesla phone:xiaomi]4m4 := map[string]string{"phone": "xiaomi", "car": "Tesla"}fmt.Println(m4) // 输出:map[car:Tesla phone:xiaomi]delete(m4, "car")fmt.Println(m4) // 输出:map[phone:xiaomi]if val, ok := m4["name"]; ok {fmt.Println("name", val)} else if _, ok = m4["car"]; ok {fmt.Println("car found")} else {fmt.Println("not find key")}for key, value := range m {fmt.Println(key, value)}list := make([]string, 0)m5 := map[string]string{"d": "dd", "c": "cc", "b": "bb", "a": "aa"}for k := range m5 {list = append(list, k) // 将key添加到切片中}sort.Strings(list) // 对切片中的元素排序for _, key := range list {fmt.Println(m5[key]) // 按顺序打印}
}