Golang教程:Map
什么是 map?
Map 是 Go 中的内置类型,它将键与值绑定到一起。可以通过键获取相应的值。
如何创建 map?
可以通过将键和值的类型传递给内置函数 make
来创建一个 map。语法为:make(map[KeyType]ValueType)
。(译者注:map 的类型表示为 map[KeyType]ValueType
)例如:
personSalary := make(map[string]int)
上面的代码创建了一个名为 personSalary
的 map。其中键的类型为 string,值的类型为 int。
map 的 0 值为 nil。试图给一个 nil map 添加元素给会导致运行时错误。因此 map 必须通过 make
来初始化(译者注:也可以使用速记声明来创建 map,见下文)。
package main import (
"fmt"
) func main() {
var personSalary map[string]int
if personSalary == nil {
fmt.Println("map is nil. Going to make one.")
personSalary = make(map[string]int)
}
}
上面的程序中,personSalary
为 nil,因此使用 make
初始化它。程序的输出为:map is nil. Going to make one.
向 map 中插入元素
插入元素给 map 的语法与数组相似。下面的代码插入一些新的元素给 map personSalary
。
package main import (
"fmt"
) func main() {
personSalary := make(map[string]int)
personSalary["steve"] =
personSalary["jamie"] =
personSalary["mike"] =
fmt.Println("personSalary map contents:", personSalary)
}
上面的程序输出:personSalary map contents: map[steve:12000 jamie:15000 mike:9000]
。
也可以在声明时初始化一个数组:
package main import (
"fmt"
) func main() {
personSalary := map[string]int {
"steve": ,
"jamie": ,
}
personSalary["mike"] =
fmt.Println("personSalary map contents:", personSalary)
}
上面的程序在声明 personSalary
的同时向其中插入了两个元素。接着插入了一个以 "mike"
为键的元素。程序的输出为:
personSalary map contents: map[steve: jamie: mike:]
string
并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators
访问 map 中的元素
现在我们已经添加了一些元素给 map,现在让我们学习如何从 map 中提取它们。根据键获取值的语法为:map[key]
,例如:
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
employee := "jamie"
fmt.Println("Salary of", employee, "is", personSalary[employee])
}
上面的程序非常简单。员工 jamie
的工资被取出并打印。程序的输出为:Salary of jamie is 15000
。
如果一个键不存在会发生什么?map 会返回值类型的 0 值。比如如果访问了 personSalary
中的不存在的键,那么将返回 int 的 0 值,也就是 0。
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
employee := "jamie"
fmt.Println("Salary of", employee, "is", personSalary[employee])
fmt.Println("Salary of joe is", personSalary["joe"])
}
上面的程序输出为:
Salary of jamie is
Salary of joe is
上面的程序返回 joe
的工资为 0。我们没有得到任何运行时错误说明键 joe
在 personSalary
中不存在。
我们如何检测一个键是否存在于一个 map 中呢?可以使用下面的语法:
value, ok := map[key]
上面的语法可以检测一个特定的键是否存在于 map 中。如果 ok
是 true,则键存在,value 被赋值为对应的值。如果 ok
为 false,则表示键不存在。
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
newEmp := "joe"
value, ok := personSalary[newEmp]
if ok == true {
fmt.Println("Salary of", newEmp, "is", value)
} else {
fmt.Println(newEmp,"not found")
} }
在上面的程序中,第 15 行,ok
应该为 false 因为 joe
不存在。因此程序的输出为:
joe not found
range for 可用于遍历 map 中所有的元素(译者注:这里 range 操作符会返回 map 的键和值)。
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
fmt.Println("All items of a map")
for key, value := range personSalary {
fmt.Printf("personSalary[%s] = %d\n", key, value)
} }
上面的程序输出如下:
All items of a map
personSalary[mike] =
personSalary[steve] =
personSalary[jamie] =
值得注意的是,因为 map 是无序的,因此对于程序的每次执行,不能保证使用 range for 遍历 map 的顺序总是一致的。
删除元素
delete(map, key)
用于删除 map 中的 key。delete
函数没有返回值。
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
fmt.Println("map before deletion", personSalary)
delete(personSalary, "steve")
fmt.Println("map after deletion", personSalary) }
上面的程序删除以 steve
为键的元素。程序输出为:
map before deletion map[steve: jamie: mike:]
map after deletion map[mike: jamie:]
map 的大小
用内置函数 len 获取 map 的大小:
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
fmt.Println("length is", len(personSalary)) }
上面程序中,len(personSalary)
获取 personSalary
的大小。上面的程序输出:length is 3
。
map 是引用类型
与切片一样,map 是引用类型。当一个 map 赋值给一个新的变量,它们都指向同一个内部数据结构。因此改变其中一个也会反映到另一个:
package main import (
"fmt"
) func main() {
personSalary := map[string]int{
"steve": ,
"jamie": ,
}
personSalary["mike"] =
fmt.Println("Original person salary", personSalary)
newPersonSalary := personSalary
newPersonSalary["mike"] =
fmt.Println("Person salary changed", personSalary)
}
上面的程序中,第 14 行,personSalary
赋值给 newPersonSalary
。下一行,将 newPersonSalary
中 mike
的工资改为 18000
。那么在 personSalary
中 mike
的工资也将变为 18000
。程序的输出如下:
Original person salary map[steve: jamie: mike:]
Person salary changed map[jamie: mike: steve:]
将 map 作为参数传递给函数也是一样的。在函数中对 map 的任何修改都会影响在调用函数中看到。
Golang教程:Map的更多相关文章
- Golang基础教程——map使用篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第7篇文章,我们来聊聊golang当中map的用法. map这个数据结构我们经常使用,存储的是key-value的键 ...
- Golang中map的三种声明方式和简单实现增删改查
package main import ( "fmt" ) func main() { test3 := map[string]string{ "one": & ...
- 总结golang之map
总结golang之map 2017年04月13日 23:35:53 趁年轻造起来 阅读数:18637 标签: golangmapgo 更多 个人分类: golang 版权声明:本文为博主原创文章, ...
- golang 中 map 转 struct
golang 中 map 转 struct package main import ( "fmt" "github.com/goinggo/mapstructure&qu ...
- golang之map的使用声明
1.map的基本介绍 map是key-value数据结构,又称为字段或者关联数组.类似其它编程语言的集合,在编程中是经常使用到的 2.map的声明 1)基本语法 var map 变量名 map[key ...
- Golang:sync.Map
由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...
- Golang教程:变量
声明单一变量 声明一个变量的语法为:var name type,例如 package main import "fmt" func main() { var age int // ...
- Golang教程:goroutine信道
在上一篇教程中,我们讨论了如何使用协程实现并发.在这篇教程中,我们将讨论信道以及如何使用信道实现协程间通信. 什么是信道 信道(Channel)可以被认为是协程之间通信的管道.与水流从管道的一端流向另 ...
- 手把手golang教程【二】——数组与切片
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第五篇,这一篇我们将会了解golang中的数组和切片的使用. 数组与切片 golang当中数组和C++中的定义类似, ...
随机推荐
- Spring学习(四)——使用Spring JDBC访问数据库
本篇我们将在上一篇http://www.cnblogs.com/wenjingu/p/3824294.html的Demo程序的基础上增加数据持久层和业务层,实现登录验证功能. 1.修改gradle文件 ...
- JS设置localStorage有效期
localStorage是一个没有时间限制的数据存储,如果没有手动删除它,它将永久保存. 但是有些时候我们又需要它在一段时间后自动删除,这里我们可以对它进行扩展. var date = new Dat ...
- select2 多选设置默认值
Select2 version 4.0.3 https://select2.github.io <select id="slroles" ng-model=" ...
- MySQL不带where条件的UPDATE和DELETE 限制操作说明
本文来自 网易云社区 . 数据安全是业务的基石,但是DBA 总会遇到救火情况,业务误删除全表或者误更新错全表业务数据,导致服务不可用 sql_safe_updates参数可以限制不带where条件的u ...
- BZOJ1901 Dynamic Rankings|带修主席树
题目链接:戳我 其实我并不会做,于是看了题解 我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构.不过一般的主席树只能搞定静态区间第K大.如果带修怎么办呢? 想一下...单点修改+区间 ...
- NetEaseGame/ATX 的MD
# ATX(AutomatorX) (中文版)[](ht ...
- javascript显示年月日时间代码显示电脑时间
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- scrapy下载中间件,UA池和代理池
一.下载中间件 框架图: 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引擎将请求传递给下载器过程中, 下载中间件可以对请 ...
- python requests 包 使用
1: 发送带 cookie 的 请求 resp = requests.get(self.url_item_list_first_page, cookies=self.cookies) >> ...
- 使用Pytesseract+Tesseract-OCR识别图片的简单步骤
1.首先安装Pytesseract,这个很简单,直接输入命令 pip install pytesseract即可 2.Tesseract-OCR https://pan.baidu.com/s/1sV ...