go数据类型Map

Map 声明,初始化,和make

go中的map相当于PHP中的关联数组,(key=>value关系集合),不同在于go中的必须指定key和value的数据类型,且是无序的,不会按照插入的顺序排序

声明

map中key 可以是任意可以用 == 或者 != 操作符比较的类型,比如 string、int、float。所以数组、切片和结构体不能作为 key ,value可以是任意类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import "fmt"

func main() {

// 声明一个map key为string类型,value为int
var mapOne map[string]int
//初始化值
mapOne = map[string]int{"one":1}
fmt.Println("mapOne初始化值: ",mapOne)
//动态赋值,长度自动扩容
mapOne["two"] = 2
fmt.Println("mapOne动态赋值,扩容: ",mapOne)


//声明一个map 并初始化
mapTwo := map[string]int{"one": 1, "two": 2}
fmt.Println("mapTwo声明并初始化:",mapTwo)
//make 声明一个map
mapThree := make(map[string]int)
mapThree = mapOne
fmt.Println("mapThree赋值为mapOne初始化值: ",mapOne)

//新增值, 更改 mapThree two
mapThree["one"] = 11
mapThree["three"] = 3
fmt.Println("mapThree修改,增加: ",mapOne)
// map为引用类型,所以当mapThree有变化是,mapOne也会变化
fmt.Println("mapOne当前值: ",mapOne)


//声明一个map,value为切片,类似于PHP中的多为数组结构
mapFour := make(map[string][]int)
mapFour["one"] = []int{1,2,3}
fmt.Println("mapFour: ",mapFour)

//mapOne初始化值: map[one:1]
//mapOne动态赋值,扩容: map[one:1 two:2]
//mapTwo声明并初始化: map[one:1 two:2]
//mapThree赋值为mapOne初始化值: map[one:1 two:2]
//mapThree修改,增加: map[one:11 three:3 two:2]
//mapOne当前值: map[one:11 three:3 two:2]
//mapFour: map[one:[1 2 3]]

}

容量

map的容量可以动态扩容的,在声明时候可以不指定长度

读取,查找,删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main

import "fmt"

func main() {

mapTwo := map[string]int{"one":1,"tow":2,"three":4}

// 通过key查找元素时,会返回两个值,一个代表值,一个bool,判断是否在字典中成功找到指定的键,不需要检查取到的值是否为 nil
// 如果存在则返回true
v,ok := mapTwo["one"]
if ok {
fmt.Println(v)
}

// 只取key,判断是否存在
_,ok = mapTwo["tow"]

if ok {
fmt.Println(ok)
}

_,ok = mapTwo["no_exist"]

if ok {
fmt.Println(ok)
}else{
fmt.Println(ok)
}

//删除元素
delete(mapTwo,"three")

if _,ok = mapTwo["three"]; ok {
fmt.Println(ok)
}else {
fmt.Println("删除key为three的值,所以取key为three时,返回false",ok)
}
}

//1
//true
//false
//删除key为three的值,所以取key为three时,返回false false

for-range

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {

mapTwo := map[string]int{"one":1,"tow":2,"three":4}

for key,value := range mapTwo {
fmt.Println(key,value)
}
}

排序

map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序

如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序(使用sort包),然后可以使用切片的 for-range 方法打印出所有的 key 和 value。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package main

import (
"fmt"
"sort"
)

var (
barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
"delta": 87, "echo": 56, "foxtrot": 12,
"golf": 34, "hotel": 16, "indio": 87,
"juliet": 65, "kili": 43, "lima": 98}
)

func main() {

fmt.Println("未排序")
for k,v := range barVal{
fmt.Println("Key: ",k,"Value: ",v)
}

fmt.Println("排序")

keys := make([]string,0)

for k := range barVal {
keys = append(keys, k)
}

fmt.Println("keys:",keys)
sort.Strings(keys)
fmt.Println("排序后的keys:",keys)

fmt.Println("排序后:")
for _,k :=range keys{
fmt.Println("Key: ",k,"Value: ",barVal[k])
}

//未排序
//Key: alpha Value: 34
//Key: bravo Value: 56
//Key: echo Value: 56
//Key: hotel Value: 16
//Key: indio Value: 87
//Key: kili Value: 43
//Key: lima Value: 98
//Key: charlie Value: 23
//Key: delta Value: 87
//Key: foxtrot Value: 12
//Key: golf Value: 34
//Key: juliet Value: 65
//排序
//keys: [echo hotel indio alpha bravo foxtrot golf juliet kili lima charlie delta]
//排序后的keys: [alpha bravo charlie delta echo foxtrot golf hotel indio juliet kili lima]
//排序后:
//Key: alpha Value: 34
//Key: bravo Value: 56
//Key: charlie Value: 23
//Key: delta Value: 87
//Key: echo Value: 56
//Key: foxtrot Value: 12
//Key: golf Value: 34
//Key: hotel Value: 16
//Key: indio Value: 87
//Key: juliet Value: 65
//Key: kili Value: 43
//Key: lima Value: 98

}