天天看点

Go语言 map的使用

map

在 C++/java中,map一般都以库的方式提供,比如在 C++中是 STL的 std::map<>,在 C#中是 Dictionary<>,在java中 HashMAP<>,在这些语言中,如果要使用 map就必须要先引入相应的库,而在 go 中,则不需要引入任何库,适用也比较方便

map是一堆键值对的未排序集合,比如一身份证作为唯一键来表示一个人的信息,则这个 map 可以定义成这个样子:

func main()  {

	//personDB 是声明的map变量名,string是键的类型,PersonInfo则是存放的类型
	var personDB map[string] PersonInfo
	//这里我们使用 make() 内置函数创建了一个新的 map() 下面是指创建了一个键类型为 string,值类型为 PersonInfo 的 map
	personDB = make(map[string] PersonInfo)
	
	//添加信息
	personDB["412725"] = PersonInfo{"123","zhangsan","beijing"}
	personDB["412725333"] = PersonInfo{"123","lisi","nanjing"}

	//判断是否存在键为 412725 如果存在 ok 的值为 true 不存在则反之
	person, ok := personDB["412725"]
	if ok {
		fmt.Println("this here",person)
		//从 PersonDB 中删除这个键为 412725 的元素,加入这个键并不存在,那么这个调用什么都不会发生,也不会存在什么副作用
		//如果我们传入的 map 变量的值为 nil 则会抛出一个异常
		delete(personDB, "412725")
	}else {
		fmt.Println("is not here")
	}

	for i, v := range personDB {
		fmt.Println("键是:",i,"/t对应的值是:",v)
	}

}
           

输出信息:

this here {123 zhangsan beijing}

键是: 412725333 /t对应的值是: {123 lisi nanjing}

从最后我们的变量可以看出 map中是存在:412725 这个键的,这个时候 ok 的值为 true,走进 if 里,执行了 delete(),最后我们的打印可以看出,这个元素已经被成功删除!

这里多说一点,另一种创建 map 直接初始化的方法,如下:

myMap = map[string] PersonInfo{ 
 "1234": PersonInfo{"1", "Jack", "Room 101,..."}, 
 ...
 ...
 ...
} 
           
map中的元素查找

go语言中,map的查找功能设计的比较精巧,其他语言中,加入我们判断能否获取到一个值不是一件容易的事情,判断能否从 map 中获取一个值的常规做法是:

  • 声明并且初始化一个变量为空
  • 试图从 map 中获取对应的键的值到该变量中
  • 判断该变量是否为空,如果为空,则表示 map 中不存在该变量

这种用法比较啰唆,而且判断变量是否为空这条语句并不能真正表意(是否成功取到对应的

值),从而影响代码的可读性和可维护性。有些库甚至会设计为因为一个键不存在而抛出异常,

让开发者用起来胆战心惊,不得不一层层嵌套try-catch语句,这更是不人性化的设计。在Go

语言中,要从map中查找一个特定的键,可以通过下面的代码来实现:

value, ok := myMap["1234"] 
if ok { // 找到了
 // 处理找到的value 
} 
           

判断是否成功找到特定的键,不需要检查取到的值是否为nil,只需查看第二个返回值ok,

这让表意清晰很多。配合:=操作符,让你的代码没有多余成分,看起来非常清晰易懂