golang map 应用实例与解析

map 简介

map 是 go 中的内置类型,它将一个值与一个键关联起来,可以使用相应的建检索值。

使用注意事项

  • map 是无序的,它不是通过index获取,而必须通过 key 获取
  • map 长度不固定,内置len() 函数适用,cap()函数不适用
  • 同一个 map中key 必须保证唯一
  • map 的 vlaue 值可以是任意类型
  • map 是引用类型

golang中的map声明非常简单,我们用map关键字表示声明一个map,然后在方括号内填上key的类型,方括号外填上value的类型。

var m map[string] int
var m map[string] float32
var m map[int] string
var m map[string] interface{}

这样我们就声明好了一个map。但是要注意,这样声明得到的是一个空的map,map的零值是nil,可以理解成空指针。
所以我们不能直接去操作这个m,否则会得到一个panic。

panic在golang当中表示非常严重不可恢复的错误,可以恢复的错误有些类似于Java或者是其他语言当中的异常,当异常出现的时候,
我们可以选择handle住它们,让程序不崩溃继续运行。而那些非常严重,无法handle的异常在golang当中称为panic。

golang当中的异常处理机制和其他语言相差很大,整体的逻辑和内核都不太一样。我们这里可以简单将它理解成error就行。

map 初始化

m := make(map[string] int)

m := make(map[string] int, 100)  //指定创建出来的map的存储容量

var m = map[string] int {"abc": 3, "ccd": 4}  //声明时初始化

map 增删改查


append(m,map[string]int{"efg":5})	// 追加至 map

m["abc"] = 4						// 替换掉原本的key、或赋值


delete(m, "abc")  					//通过delete关键字删除。

在golang当中如果要删除的key值原本就不在map当中,那么当我们调用了delete之后,不会发生异常错误。
但是有一点,必须要保证传入的map不为nil,否则也会引起panic。

实例 1

package main

 import (
	 "fmt"
	 "strings"
 )


func WordCnt(s string) map[string] int {
	cnt := make(map[string] int)

	var n = 0
	for _, str := range strings.Split(s," "){
		n = n +1
		cnt[str] = n
	}
	return cnt
}


 func main () { 
	var str = "abc efg hig lkm"
	res := make(map[string] int)
	res = WordCnt(str)
	fmt.Println("result:",res)

	for k,v := range res {
		fmt.Printf("%v %v \t",k,v)
	}

	fmt.Println("\n\r")

	for k,v := range res {
                fmt.Printf("%v %v \t",k,v)
        }
	fmt.Println("\n\r")

 }

运行效果

robot@ubuntu:~/gomod/src/map$ go run wordCnt.go 
result: map[abc:1 efg:2 hig:3 lkm:4]
abc 1 	efg 2 	hig 3 	lkm 4 	

hig 3 	lkm 4 	abc 1 	efg 2 	

robot@ubuntu:~/gomod/src/map$ go run wordCnt.go 
result: map[abc:1 efg:2 hig:3 lkm:4]
abc 1 	efg 2 	hig 3 	lkm 4 	

abc 1 	efg 2 	hig 3 	lkm 4 	

实例 2

package main

import (
	"fmt"
	"strings"
)

func main() {
	tt := "zhangsan, lisi, wangwu, 李逵"
	res := make(map[string]interface{})
	ret := make([]map[string]interface{},0)
	fmt.Println("start --> ret \n",ret)

	for k,v := range strings.Split(tt,",") {
		fmt.Println(k,"ret: ",ret)
		res["name"] = v
		
		fmt.Println(k,"line ret: ", ret)
	//	ret = append(ret, res)
		ret = append(ret,map[string]interface{}{"name":v})
		fmt.Println(k,"for res:",res)
		fmt.Printf("\n\r")
	}
	
		fmt.Println("line ret: ", ret)
}

运行效果

robot@ubuntu:~/gomod/src/map$ go run mapAppend.go 
start --> ret 
 []
0 ret:  []
0 line ret:  []
0 for res: map[name:zhangsan]

1 ret:  [map[name:zhangsan]]
1 line ret:  [map[name:zhangsan]]
1 for res: map[name: lisi]

2 ret:  [map[name:zhangsan] map[name: lisi]]
2 line ret:  [map[name:zhangsan] map[name: lisi]]
2 for res: map[name: wangwu]

3 ret:  [map[name:zhangsan] map[name: lisi] map[name: wangwu]]
3 line ret:  [map[name:zhangsan] map[name: lisi] map[name: wangwu]]
3 for res: map[name: 李逵]

line ret:  [map[name:zhangsan] map[name: lisi] map[name: wangwu] map[name: 李逵]]

实例 3 并发

package main
import (
	"fmt"
	"sync"
	"time"
)

type Map struct {
	m map[int]int
	sync.RWMutex
}

func (this *Map) Get(k int) int {
	this.RLock()
	defer this.RUnlock()

	v := this.m[k]
	return v
}

func (this *Map) Set(k,v int) {
	this.Lock()
	defer this.Unlock()

	this.m[k] = v
}

func main() {
	newMap := &Map{m : make(map[int]int)}

	for i := 0; i < 100; i++ {
		go newMap.Set(i,i)
	}

	for n := 0; n < 100; n++ {
		go fmt.Println(n,newMap.Get(n))
	}

	time.Sleep(time.Second * 2)
}

运行效果

package main
import (
	"fmt"
	"sync"
	"time"
)

type Map struct {
	m map[int]int
	sync.RWMutex
}

func (this *Map) Get(k int) int {
	this.RLock()
	defer this.RUnlock()

	v := this.m[k]
	return v
}

func (this *Map) Set(k,v int) {
	this.Lock()
	defer this.Unlock()

	this.m[k] = v
}

func main() {
	newMap := &Map{m : make(map[int]int)}

	for i := 0; i < 100; i++ {
		go newMap.Set(i,i)
	}

	for n := 0; n < 100; n++ {
		go fmt.Println(n,newMap.Get(n))
	}

	time.Sleep(time.Second * 2)
}

运行效果

robot@ubuntu:~/gomod/src/map$ go run map.go 
99 0
72 72
73 73
74 74
75 75
76 76
77 77
80 80
45 45
90 90
47 47
48 48
88 88
49 49
83 83
54 54
4 4
20 20
89 89
8 8
46 46
81 81
82 82
78 78
91 0
52 52
92 0
93 0
94 0
23 23
53 53
79 79
40 40
85 85
44 44
96 0
87 87
62 62
55 55
56 56
57 57
97 0
58 58
59 59
60 60
61 61
17 17
98 0
0 0
66 66
1 1
2 2
3 3
63 63
50 50
64 64
67 67
65 65
68 68
30 30
18 18
19 19
71 71
5 5
6 6
7 7
51 51
21 21
22 22
95 0
9 9
10 10
11 11
69 69
12 12
13 13
14 14
15 15
16 16
26 26
24 24
25 25
70 70
37 37
31 31
32 32
33 33
34 34
35 35
36 36
28 28
27 27
29 29
38 38
42 42
41 41
43 43
39 39
86 86
84 84

参考连接:
https://blog.csdn.net/xiaotai1234/article/details/112388148

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值