mirror of
https://gitee.com/shikong-sk/golang-study
synced 2025-02-23 23:42:15 +08:00
400 lines
8.5 KiB
Markdown
400 lines
8.5 KiB
Markdown
**
|
||
本章目录:**
|
||
|
||
- 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`的数据结构, 并且它是引用类型,所以必须初始化值周才能进行使用。
|
||
|
||
**语法定义:**
|
||
|
||
```javascript
|
||
map[KeyType]ValueType
|
||
|
||
// # 参数说明:
|
||
- KeyType:表示键的类型。
|
||
- ValueType:表示键对应的值的类型。
|
||
```
|
||
|
||
Tips : map类型的变量`默认初始值为nil`,需要使用`make()函数来分配内存`。语法为:`make(map[KeyType]ValueType, [cap])`, 其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。
|
||
|
||
|
||
|
||
# 2.Map 基础使用
|
||
|
||
描述:Map 中的数据都是成对出现的其Map的基本使用示例代码如下:
|
||
|
||
```go
|
||
// 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]`
|
||
|
||
```go
|
||
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` 就可以搞定。
|
||
|
||
```go
|
||
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:` 表示要删除的键值对的键。
|
||
|
||
```go
|
||
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类型变量。
|
||
|
||
简单示例:
|
||
|
||
|
||
|
||
```go
|
||
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)
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
执行结果:
|
||
|
||
```go
|
||
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中值为切片类型的操作:
|
||
|
||
```go
|
||
// 值为切片类型的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
|
||
}
|
||
```
|
||
|
||
执行结果:
|
||
|
||
```go
|
||
初始化 sliceMap 其值 : map[]
|
||
map[City:[北京 上海] Country:[中国 台湾]]
|
||
```
|
||
|
||
|
||
|
||
Tips : 非常重要、重要 `Slice切片与Map` 在使用时一定要做初始化操作(在内存空间申请地址)。
|
||
|
||
|
||
|
||
# 7.示例演示
|
||
|
||
**1.Map类型的基础示例**
|
||
|
||
```go
|
||
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, " ")
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
执行结果:
|
||
|
||
```go
|
||
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**
|
||
|
||
```go
|
||
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])
|
||
}
|
||
}
|
||
```
|
||
|
||
执行结果:
|
||
|
||
```go
|
||
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 映射`有序与无序输出演示。
|
||
|
||
```go
|
||
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)
|
||
}
|
||
}
|
||
```
|
||
|
||
执行结果:
|
||
|
||
```go
|
||
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
|
||
``` |