1
- 13 - Map 集合
1
+ 13 - Map
2
2
========================
3
3
4
4
上一节:[ 第十二篇 变参函数] ( /docs/golang_tutorial_12.md )
8
8
9
9
## 什么是 map?
10
10
11
- Map 是 Go 中的内置类型,它将键与值绑定到一起。可以通过键获取相应的值。
11
+ Map 是 Go 中的内置类型,它将键与值绑定到一起。可以通过键获取相应的值。Map与其他语言(例如Python)中的dictionary非常相似。
12
12
13
- ## 如何创建 map?
13
+ ## 如何创建 map?
14
14
15
15
可以通过将键和值的类型传递给内置函数 ` make ` 来创建一个 ` map ` 。语法为:` make(map[KeyType]ValueType) ` 。(译者注:` map ` 的类型表示为 ` map[KeyType]ValueType ` )例如:
16
16
17
17
``` golang
18
18
personSalary := make (map [string ]int )
19
19
```
20
20
21
- 上面的代码创建了一个名为 ` personSalary ` 的 map。其中键的类型为 string,值的类型为 int。
21
+ 上面的代码创建了一个名为 ` personSalary ` 的 map。其中键的类型为 ` string ` ,值的类型为 ` int ` 。
22
22
23
- ** map 的 0 值为 ` nil ` 。试图给一个 nil map 添加元素给会导致运行时错误。因此 map 必须通过 make 来初始化** (译者注:也可以使用速记声明来创建 map,见下文)。
23
+ ** map 的 0 值为 ` nil ` 。试图给一个 nil map 添加元素给会导致运行时错误。因此 map 必须通过 ` make ` 来初始化** (译者注:也可以使用速记声明来创建 map,见下文)。
24
24
25
25
``` golang
26
26
package main
@@ -42,7 +42,8 @@ func main() {
42
42
43
43
## 向 map 中插入元素
44
44
45
- 插入元素给 map 的语法与数组相似。下面的代码插入一些新的元素给 ` map personSalary ` 。
45
+ 插入元素给 map 的语法与数组相似。下面的代码插入一些新的元素给名为 ` personSalary ` 的 map。
46
+
46
47
``` golang
47
48
package main
48
49
@@ -61,7 +62,7 @@ func main() {
61
62
62
63
上面的程序输出:` personSalary map contents: map[steve:12000 jamie:15000 mike:9000] ` 。
63
64
64
- 也可以在声明时初始化一个数组 :
65
+ 也可以在声明时初始化一个 map :
65
66
66
67
``` golang
67
68
package main
@@ -86,7 +87,7 @@ func main() {
86
87
personSalary map contents: map [steve:12000 jamie:15000 mike:9000 ]
87
88
```
88
89
89
- ` string ` 并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators
90
+ ` string ` 并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。甚至用户自定义的类型,如 ` struct ` ,也可以作为键。 如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators
90
91
91
92
## 访问 map 中的元素
92
93
@@ -140,7 +141,7 @@ Salary of jamie is 15000
140
141
Salary of joe is 0
141
142
```
142
143
143
- 上面的程序返回 ` joe ` 的工资为` 0 ` 。我们没有得到任何运行时错误说明键 joe 在 ` personSalary ` 中不存在。
144
+ 上面的程序返回 ` joe ` 的工资为` 0 ` 。我们没有得到任何运行时错误说明键 ` joe ` 在 ` personSalary ` 中不存在。
144
145
145
146
我们如何检测一个键是否存在于一个 map 中呢?可以使用下面的语法:
146
147
@@ -180,7 +181,9 @@ func main() {
180
181
joe not found
181
182
```
182
183
183
- range for 可用于遍历 map 中所有的元素(译者注:这里 range 操作符会返回 map 的键和值)。
184
+ ## 遍历 map 中的所有元素
185
+
186
+ ` for ` 循环的 ` range ` 形式可用于遍历 map 中所有的元素(译者注:这里 ` range ` 操作符会返回 map 的键和值)。
184
187
185
188
``` golang
186
189
package main
@@ -193,8 +196,8 @@ func main() {
193
196
personSalary := map [string ]int {
194
197
" steve" : 12000 ,
195
198
" jamie" : 15000 ,
199
+ " mike" : 9000 ,
196
200
}
197
- personSalary[" mike" ] = 9000
198
201
fmt.Println (" All items of a map" )
199
202
for key , value := range personSalary {
200
203
fmt.Printf (" personSalary[%s ] = %d \n " , key, value)
@@ -211,11 +214,11 @@ personSalary[steve] = 12000
211
214
personSalary[jamie] = 15000
212
215
```
213
216
214
- 值得注意的是,因为 map 是无序的,因此对于程序的每次执行,不能保证使用 range for 遍历 map 的顺序总是一致的。
217
+ 值得注意的是,因为 map 是无序的,因此对于程序的每次执行,不能保证使用 ` for range ` 遍历 map 的顺序总是一致的,而且遍历的顺序也不完全与元素添加的顺序一致。
215
218
216
219
## 删除元素
217
220
218
- ` delete(map, key) ` 用于删除 map 中的 key。 delete 函数没有返回值。
221
+ ` delete(map, key) ` 用于删除 map 中的键。 ` delete ` 函数没有返回值。
219
222
220
223
``` golang
221
224
package main
@@ -244,6 +247,62 @@ map before deletion map[steve:12000 jamie:15000 mike:9000]
244
247
map after deletion map [mike:9000 jamie:15000 ]
245
248
```
246
249
250
+ 如果我们试图删除一个原 map 中不存在的键,运行 ` delete ` 时仍不会报错。
251
+
252
+ ## 结构体 map (Map of Structs)
253
+
254
+ 目前我们编写了存储员工工资的 map,那么可否将员工的国籍也存储在 map 中呢?这可以通过结构体 map 来完成。每个员工可以用一个包含了"工资"和"国籍"的结构体来表示,这些结构体将被存储在一个键为 ` string ` 类型,值为 ` struct ` 类型的 map 中。
255
+
256
+ ``` golang
257
+ package main
258
+
259
+ import (
260
+ " fmt"
261
+ )
262
+
263
+ type employee struct {
264
+ salary int
265
+ country string
266
+ }
267
+
268
+ func main () {
269
+ emp1 := employee{
270
+ salary: 12000 ,
271
+ country: " USA" ,
272
+ }
273
+ emp2 := employee{
274
+ salary: 14000 ,
275
+ country: " Canada" ,
276
+ }
277
+ emp3 := employee{
278
+ salary: 13000 ,
279
+ country: " India" ,
280
+ }
281
+ employeeInfo := map [string ]employee{
282
+ " Steve" : emp1,
283
+ " Jamie" : emp2,
284
+ " Mike" : emp3,
285
+ }
286
+
287
+ for name , info := range employeeInfo {
288
+ fmt.Printf (" Employee: %s Salary:$%d Country: %s \n " , name, info.salary , info.country )
289
+ }
290
+
291
+ }
292
+ ```
293
+
294
+ 以上程序中,` employee ` 结构体包含了 ` salary ` 和 ` country ` 。
295
+
296
+ 在第25行,我们创建了一个 map,键为字符串类型,值为 ` employee ` 结构体,并添加了我们创建的三个员工。
297
+
298
+ 在第31行,我们遍历这个 map,打印出所有员工的信息:
299
+
300
+ ``` golang
301
+ Employee: Mike Salary :$13000 Country : India
302
+ Employee: Steve Salary :$12000 Country : USA
303
+ Employee: Jamie Salary :$14000 Country : Canada
304
+ ```
305
+
247
306
## map 的大小
248
307
249
308
用内置函数 ` len ` 获取 map 的大小:
@@ -303,7 +362,7 @@ Person salary changed map[jamie:15000 mike:18000 steve:12000]
303
362
304
363
## 比较 map
305
364
306
- map 不能通过 ` == ` 操作符比较是否相等。` == ` 操作符只能用来检测 map 是否为 nil。
365
+ map 不能通过 ` == ` 操作符比较是否相等。` == ` 操作符只能用来检测 map 是否为 ` nil ` 。
307
366
308
367
``` golang
309
368
package main
@@ -323,7 +382,7 @@ func main() {
323
382
324
383
上面的程序将会报错:` invalid operation: map1 == map2 (map can only be compared to nil) ` 。
325
384
326
- 比较两个 map 是否相等的方式是一一比较它们的元素是否相等。我会鼓励你为此编写一个程序,使其工作:)
385
+ 比较两个 map 是否相等的方式是一一比较它们的元素是否相等。希望你能自己探索并编写一个达成这一功能的程序:)
327
386
328
387
我(原文作者)已经将我们讨论的所有概念汇总到一个程序中,你可以从 [ github] ( https://github.com/golangbot/arraysandslices ) 下载。
329
388
@@ -363,6 +422,8 @@ func main(){
363
422
" school" :" BAT_UN"
364
423
}
365
424
fmt.Println (m4)
425
+
426
+ // 方式五
366
427
m5 := make (map [string ][string ])
367
428
m5[" name" ] = " Linux"
368
429
m5[" school" ] = " Unix"
@@ -397,7 +458,7 @@ func main(){
397
458
fmt.Println (m_b, ok) // OK b true
398
459
399
460
// 迭代操作
400
- s_map := make ([]map [int ]string ,5 ) // 以 map 为元素的slice 使用 make 创建一个切片,元素的slic
461
+ s_map := make ([]map [int ]string ,5 ) // 以 map 为元素的 slice 使用 make 创建一个切片,切片内的每个元素为一个 map
401
462
for _,v := range s_map {
402
463
v = make (map [int ]string ) // v 是值的拷贝
403
464
v[1 ] = " OK"
0 commit comments