-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
155 lines (132 loc) · 2.98 KB
/
main.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// https://blog.golang.org/go-maps-in-action
package main
import (
"fmt"
"sort"
"sync"
)
func Common() {
var m map[string]int
fmt.Println(m)
fmt.Println(m == nil)
// m["aa"] = 1 // panic:
mm := make(map[string]int)
mm["aa"] = 1 // ok
fmt.Println(mm["bb"])
fmt.Println(len(mm))
if v, ok := mm["bb"]; ok {
fmt.Println(v)
}
commits := map[string]int{
"rsc": 3711,
"r": 2138,
"gri": 1908,
"adg": 912,
}
fmt.Println(commits)
}
func ZeroBool() {
type Node struct {
Next *Node
Value interface{}
}
var first *Node
visited := make(map[*Node]bool)
for n := first; n != nil; n = n.Next {
if visited[n] { // zero value of bool is (false, bool), so no need 2-value form
fmt.Println("cycle detected")
break
}
visited[n] = true
fmt.Println(n.Value)
}
}
func ZeroSlice() {
type Person struct {
Name string
Likes []string
}
var people []*Person
likes := make(map[string][]*Person)
for _, p := range people {
for _, l := range p.Likes {
likes[l] = append(likes[l], p) // zero value of slice is (nil, Type), so no need 2-value form
}
}
for _, p := range likes["cheese"] {
fmt.Println(p.Name, "likes cheese.")
}
fmt.Println(len(likes["bacon"]), "people like bacon.")
}
func MapMap() {
// slices, maps, and functions cannot be compared, so cannot be key
// Each key of the outer map is the path to a web page with its own inner map. Each inner map key is a two-letter country code. This expression retrieves the number of times an Australian has loaded the documentation page:
hits := make(map[string]map[string]int)
// Unfortunately, this approach becomes unwieldy when adding data, as for any given outer key you must check if the inner map exists, and create it if needed:
add := func(m map[string]map[string]int, path, country string) {
mm, ok := m[path]
if !ok {
mm = make(map[string]int)
m[path] = mm
}
mm[country]++
}
add(hits, "/doc/", "au")
n := hits["/doc/"]["au"]
fmt.Println(n)
}
// same example as MapMap
func StructMap() {
type Key struct {
Path, Country string
}
hits := make(map[Key]int)
hits[Key{"/ref/spec", "ch"}]++
n := hits[Key{"/ref/spec", "ch"}]
fmt.Println(n)
}
// ConcurrencyMap using sync.RWMutex for maps are not safe for concurrent use.
func ConcurrencyMap() {
var wg sync.WaitGroup
var counter = struct {
sync.RWMutex
m map[string]int
}{m: make(map[string]int)}
wg.Add(1)
go func() {
counter.Lock()
counter.m["some_key"]++
counter.Unlock()
wg.Done()
}()
wg.Add(1)
go func() {
counter.RLock()
n := counter.m["some_key"]
counter.RUnlock()
fmt.Println("some_key:", n)
wg.Done()
}()
wg.Wait()
}
// OrderMap using a slice keep the order of items in map for map do not keep iterator order.
func OrderMap() {
var m map[int]string
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
}
func main() {
Common()
ZeroBool()
ZeroBool()
MapMap()
StructMap()
ConcurrencyMap()
OrderMap()
}