map是一堆键值对的未排序集合。比如以身份证号作为唯一键来标识一个人的信息,则这个 map可以定义为代码清单 2-3所示的方式。
代码清单2-3 map1.go package main
import "fmt"
// PersonInfo是一个包含个人详细信息的类型 type PersonInfo struct {
ID string
Name string Address string
}
func main() {
var personDB map[string] PersonInfo
personDB = make(map[string] PersonInfo)
// 往这个map里插入几条数据
personDB["12345"] = PersonInfo{"12345", "Tom", "Room 203,..."}
personDB["1"] = PersonInfo{"1", "Jack", "Room 101,..."}
// 从这个map查找键为"1234"的信息 person, ok := personDB["1234"]
// ok是一个返回的bool型,返回true表示找到了对应的数据
if ok {
fmt.Println("Found person", person.Name, "with ID 1234.")
} else {
fmt.Println("Did not find person with ID 1234.")
} }
上面这个简单的例子基本上已经覆盖了map的主要用法,下面对其中的关键点进行细述。
1. 变量声明
map的声明基本上没有多余的元素,比如: var myMap map[string] PersonInfo
其中,myMap是声明的map变量名,string是键的类型,PersonInfo则是其中所存放的值类型。
2. 创建
我们可以使用Go语言内置的函数make()来创建一个新map。
下面的这个例子创建了一个键 类型为string、值类型为PersonInfo的map:
myMap = make(map[string] PersonInfo) 也可以选择是否在创建时指定该map的初始存储能力,下面的例子创建了一个初始存储能力
为100的map:
myMap = make(map[string] PersonInfo, 100)
关于存储能力的说明,可以参见2.3.6节中的内容。 创建并初始化map的代码如下:
myMap = map[string] PersonInfo{
"1234": PersonInfo{"1", "Jack", "Room 101,..."},
}
3. 元素赋值
赋值过程非常简单明了,就是将键和值用下面的方式对应起来即可:
myMap["1234"] = PersonInfo{"1", "Jack", "Room 101,..."}
4. 元素删除
delete(myMap, "1234") 上面的代码将从myMap中删除键为“1234”的键值对。如果“1234”这个键不存在,那么这个调 8
用将什么都不发生,也不会有什么副作用。但是如果传入的map变量的值是nil,该调用将导致 程序抛出异常(panic)。
5. 元素查找 在Go语言中,map的查找功能设计得比较精巧。而在其他语言中,我们要判断能否获取到一
个值不是件容易的事情。判断能否从map中获取一个值的常规做法是:
(1) 声明并初始化一个变量为空;
(2) 试图从map中获取相应键的值到该变量中;
(3) 判断该变量是否依旧为空,如果为空则表示map中没有包含该变量。 这种用法比较啰唆,而且判断变量是否为空这条语句并不能真正表意(是否成功取到对应的
值),从而影响代码的可读性和可维护性。有些库甚至会设计为因为一个键不存在而抛出异常, 让开发者用起来胆战心惊,不得不一层层嵌套try-catch语句,这更是不人性化的设计。在Go 语言中,要从map中查找一个特定的键,可以通过下面的代码来实现:
value, ok := myMap["1234"] ifok{// 找到了
// 处理找到的value }
判断是否成功找到特定的键,不需要检查取到的值是否为nil,只需查看第二个返回值ok, 这让表意清晰很多。配合:=操作符,让你的代码没有多余成分,看起来非常清晰易懂。