8.5 KiB
** 本章目录:**
-
0x02 Go语言基础之Map映射
-
- 1.Map 声明定义
- 2.Map 基础使用
- 3.Map 键值遍历
- 4.Map 键值删除
- 5.值为map类型的切片
- 6.值为切片类型的map
- 7.示例演示
0x02 Go语言基础之Map映射
描述: Go语言中提供的映射关系容器为map, 其内部使用散列表(hash)实现。
1.Map 声明定义
描述: Map 是一种无序的基于key-value
的数据结构, 并且它是引用类型,所以必须初始化值周才能进行使用。
语法定义:
map[KeyType]ValueType
// # 参数说明:
- KeyType:表示键的类型。
- ValueType:表示键对应的值的类型。
Tips : map类型的变量默认初始值为nil
,需要使用make()函数来分配内存
。语法为:make(map[KeyType]ValueType, [cap])
, 其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。
2.Map 基础使用
描述:Map 中的数据都是成对出现的其Map的基本使用示例代码如下:
// 1.采用Make初始化Map类型的变量。
scoreMap := make(map[string]int, 8)
scoreMap["小明"] = 100
fmt.Println(scoreMap["小明"])
fmt.Printf("type of a:%T\n", scoreMap)
// 2.在声明时填充元素。
userInfo := map[string]string{
"username": "WeiyiGeek",
"password": "123456",
}
fmt.Println(userInfo)
3.Map 键值遍历
描述: 在进行Map类型的变量遍历之前,我们先学习判断map中键是否存在。
(1) 键值判断
描述: 判断Map中某个键是否存在可以采用如下特殊写法: value, ok := map[key]
scoreMap := make(map[string]int)
scoreMap["小明"] = 100
value, ok := scoreMap["张三"]
if ok {
fmt.Println("scoreMap 存在该 '张三' 键")
} else {
fmt.Println("scoreMap 不存在该键值")
}
(2) 键值遍历
描述: Go 语言中不像Python语言一样有多种方式进行遍历, 大道至简就 for...range
遍历 Map
就可以搞定。
scoreMap := make(map[string]int)
scoreMap["Go"] = 90
scoreMap["Python"] = 100
scoreMap["C++"] = 60
// 遍历 k-v 写法
for k, v := range scoreMap {
fmt.Println(k, v)
}
// 遍历 k 写法
for k := range scoreMap {
fmt.Println(k)
}
// 遍历 v 写法
for _, v := range scoreMap {
fmt.Println(v)
}
Tips :遍历map时的元素顺序与添加键值对的顺序无关。
4.Map 键值删除
描述: 我们可使用 delete() 内建函数
从map中删除一组键值对, delete()
函数的格式如下: delete(map, key)
其中 map:
表示要删除键值对的map, key:
表示要删除的键值对的键。
scoreMap := make(map[string]int)
scoreMap["张三"] = 90
scoreMap["小明"] = 100
delete(scoreMap, "小明" ) // 将`小明:100`从map中删除
for k,v := range scoreMap{
fmt.Println(k, v)
}
5.值为map类型的切片
描述: 第一次看到时可能比较绕,其实可以看做在切片中存放Map类型变量。
简单示例:
func demo3() {
var mapSlice = make([]map[string]string, 3)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
fmt.Println()
// 对切片中的map元素进行初始化
mapSlice[0] = make(map[string]string, 10)
mapSlice[1] = make(map[string]string, 10)
mapSlice[2] = make(map[string]string, 10)
mapSlice[0]["name"] = "WeiyiGeek"
mapSlice[0]["sex"] = "Man"
mapSlice[1]["姓名"] = "极客"
mapSlice[1]["性别"] = "男"
mapSlice[2]["hobby"] = "Computer"
mapSlice[2]["爱好"] = "电脑技术"
for i, v := range mapSlice {
//fmt.Printf("index:%d value:%v\n", i, v)
for _, value := range v {
fmt.Printf("index:%d value:%v\n", i, value)
}
}
}
执行结果:
index:0 value:map[]
index:1 value:map[]
index:2 value:map[]
index:0 value:Man
index:0 value:WeiyiGeek
index:1 value:极客
index:1 value:男
index:2 value:Computer
index:2 value:电脑技术
6.值为切片类型的map
描述: 同样在Map中存放切片类型的数据。
代码演示了map中值为切片类型的操作:
// 值为切片类型的map
func demo4() {
var sliceMap = make(map[string][]string, 3)
var key = [2]string{"Country", "City"}
fmt.Println("初始化 sliceMap 其值 : ", sliceMap)
for _, v := range key {
// 判断键值是否存在如果不存在则初始化一个容量为2的切片
value, ok := sliceMap[v]
if !ok {
value = make([]string, 0, 2)
}
if v == "Country" {
value = append(value, "中国", "台湾")
} else {
value = append(value, "北京", "上海")
}
// 将切片值赋值给Map类型的变量
sliceMap[v] = value
}
执行结果:
初始化 sliceMap 其值 : map[]
map[City:[北京 上海] Country:[中国 台湾]]
Tips : 非常重要、重要 Slice切片与Map
在使用时一定要做初始化操作(在内存空间申请地址)。
7.示例演示
1.Map类型的基础示例
func demo1() {
// 1.Map 定义
var a1 map[string]int8 // (未分配内存)
fmt.Println("Map 类型 的 a1 变量 :", a1)
if a1 == nil {
fmt.Println("默认初始化的Map类型的a1变量值: nil")
}
// 2.基本使用利用Make进行分配内存空间存储Map。
b1 := make(map[string]string, 8)
b1["姓名"] = "WeiyiGeek"
b1["性别"] = "男|man"
b1["爱好"] = "计算机技术"
b1["出生日期"] = "2021-08-08"
// 指定输出
fmt.Printf("b1['姓名'] = %v \n", b1["姓名"])
// 整体输出
fmt.Printf("Map b1 Type: %T , Map b1 Value: %v \n", b1, b1)
// 3.在声明时填充元素。
c1 := map[string]string{
"username": "WeiyiGeek",
"sex": "Man",
"hobby": "Computer",
}
// 指定输出
fmt.Printf("c1['username'] = %v \n", c1["username"])
// 整体输出
fmt.Printf("Map c1 Type: %T , Length : %d , Map c1 Value: %v \n", c1, len(c1), c1)
// 4.判断c1中的键值时候是否存在 sex Key.
value, ok := c1["sex"]
if ok {
fmt.Println("c1 Map 变量中存在 'sex' 键 = ", value)
} else {
fmt.Println("c1 Map 变量中不存在 sex 键")
}
// 5.遍历Map
for k, v := range b1 {
fmt.Println(k, "=", v)
}
// 6.删除指定键值对,例如删除c1中的hobby键值。
delete(c1, "hobby")
fmt.Printf("Map 现存在的键 : ")
for k := range c1 {
fmt.Print(k, " ")
}
}
执行结果:
Map 类型 的 a1 变量 : map[]
默认初始化的Map类型的a1变量值: nil
b1['姓名'] = WeiyiGeek
Map b1 Type: map[string]string , Map b1 Value: map[出生日期:2021-08-08 姓名:WeiyiGeek 性别:男|man 爱好:计算机技术]
c1['username'] = WeiyiGeek
Map c1 Type: map[string]string , Length : 3 , Map c1 Value: map[hobby:Computer sex:Man username:WeiyiGeek]
c1 Map 变量中存在 'sex' 键 = Man
出生日期 = 2021-08-08
姓名 = WeiyiGeek
性别 = 男|man
爱好 = 计算机技术
Map 现存在的键 : username sex
2.按照指定顺序遍历map
func demo2() {
rand.Seed(time.Now().UnixNano()) //初始化随机数种子
// 申请并初始化一个长度为 200 的 Map
var scoreMap = make(map[string]int, 200)
for i := 0; i < 20; i++ {
key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
value := rand.Intn(100) //生成0~99的随机整数
scoreMap[key] = value
}
//取出map中的所有key存入切片keys
var keys = make([]string, 0, 200)
for key := range scoreMap {
keys = append(keys, key)
}
//对切片进行排序
sort.Strings(keys)
//按照排序后的key遍历map
for _, key := range keys {
fmt.Println(key, scoreMap[key])
}
}
执行结果:
stu00 4
stu01 48
stu02 66
stu03 18
stu04 13
stu05 89
stu06 80
stu07 16
stu08 11
stu09 26
stu10 42
stu11 45
stu12 24
stu13 47
stu14 92
stu15 77
stu16 12
stu17 16
stu18 17
stu19 76
Tips : 探究上述示例中Array 数组、Slice 切片、Map 映射
有序与无序输出演示。
func demo5() {
// Array
var Arr = [...]int{1, 2, 6, 4, 5}
// Slice
var Sli = []int{1, 2, 6, 4, 5}
// Map
var Map = map[string]int{
"a1": 1,
"b2": 2,
"c3": 3,
"d6": 6,
"e5": 5,
}
fmt.Printf("Type : %T, Value : %v \n", Arr, Arr)
for _, A := range Arr {
fmt.Printf("%v ", A)
}
fmt.Println()
fmt.Printf("Type : %T, Value : %v \n", Sli, Sli)
for _, S := range Sli {
fmt.Printf("%v ", S)
}
fmt.Println()
fmt.Printf("Type : %T, Value : %v \n", Map, Map)
for _, M := range Map {
fmt.Printf("%v ", M)
}
}
执行结果:
Type : [5]int, Value : [1 2 6 4 5]
1 2 6 4 5
Type : []int, Value : [1 2 6 4 5]
1 2 6 4 5
Type : map[string]int, Value : map[a1:1 b2:2 c3:3 d6:6 e5:5]
1 2 3 6 5