内容简介:《Go语言四十二章经》第十三章 字典(Map)作者:李骁map 是引用类型,可以使用如下声明:
《Go语言四十二章经》第十三章 字典(Map)
作者:李骁
13.1 字典(Map)
map 是引用类型,可以使用如下声明:
var map1 map[keytype]valuetype var map1 map[string]int
([keytype] 和 valuetype 之间允许有空格,但是 Gofmt 移除了空格)
在声明的时候不需要知道 map 的长度,map 是可以动态增长的。
未初始化的 map 的值是 nil。
key 可以是任意可以用 == 或者 != 操作符比较的类型,比如 string、int、float。所以数组、切片和结构体不能作为 key (译者注:含有数组切片的结构体不能作为 key,只包含内建类型的 struct 是可以作为 key 的),但是指针和接口类型可以。如果要用结构体作为 key 可以提供 Key() 和 Hash() 方法,这样可以通过结构体的域计算出唯一的数字或者字符串的 key。
value 可以是任意类型的;通过使用空接口类型,我们可以存储任意值,但是使用这种类型作为值时需要先做一次类型断言。map 也可以用函数作为自己的值,这样就可以用来做分支结构:key 用来选择要执行的函数。
map 传递给函数的代价很小:在 32 位机器上占 4 个字节,64 位机器上占 8 个字节,无论实际上存储了多少数据。
通过 key 在 map 中寻找值是很快的,比线性查找快得多,但是仍然比从数组和切片的索引中直接读取要慢 100 倍;所以如果你很在乎性能的话还是建议用切片来解决问题。
map 可以用 {key1: val1, key2: val2} 的描述方法来初始化,就像数组和结构体一样。
map 是 引用类型 的: 内存用 make 方法来分配。
map 的初始化:
var map1 = make(map[keytype]valuetype)
map 容量: 和数组不同,map 可以根据新增的 key-value 对动态的伸缩,因此它不存在固定长度或者最大限制。但是你也可以选择标明 map 的初始容量 capacity,就像这样:make(map[keytype]valuetype,cap)。
例如:
map2 := make(map[string]float32, 100)
当 map 增长到容量上限的时候,如果再增加新的 key-value 对,map 的大小会自动加 1。所以出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明。
在一个 nil 的slice中添加元素是没问题的,但对一个map做同样的事将会生成一个运行时的panic。
Works: package main func main() { var s []int s = append(s, 1) } Fails: package main func main() { var m map[string]int m["one"] = 1 // 错误 }
map的key访问,val1, isPresent := map1[key1] 或者 val1 = map1[key1] 的方法获取 key1 对应的值 val1。
一般判断是否某个key存在,不使用值判断,而使用下面的方式:
if _, ok := x["two"]; !ok { fmt.Println("no entry") }
用切片作为 map 的值
既然一个 key 只能对应一个 value,而 value 又是一个原始类型,那么如果一个 key 要对应多个值怎么办?例如,当我们要处理unix机器上的所有进程,以父进程(pid 为整形)作为 key,所有的子进程(以所有子进程的 pid 组成的切片)作为 value。通过将 value 定义为 []int 类型或者其他类型的切片,就可以优雅的解决这个问题。
这里有一些定义 map 的例子:
// 声明但未初始化map,此时是map的零值状态 map1 := make(map[string]string, 5) map2 := make(map[string]string) // 创建了初始化了一个空的的map,这个时候没有任何元素 map3 := map[string]string{} // map中有三个值 map4 := map[string]string{"a": "1", "b": "2", "c": "3"}
从 map1 中删除 key1: 直接 delete(map1, key1) 就可以。如果 key1 不存在,该操作不会产生错误。
Delete(map4, "a")
map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序。 如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序(使用 sort 包)。
13.2 "range"语句中更新引用元素的值
在"range"语句中生成的数据的值是真实集合元素的拷贝。它们不是原有元素的引用。 这意味着更新这些值将不会修改原来的数据。同时也意味着使用这些值的地址将不会得到原有数据的指针。
package main import "fmt" func main() { data := []int{1, 2, 3} for _, v := range data { v *= 10 // 通常数据项不会改变 } fmt.Println("data:", data) // 程序输出: [1 2 3] }
如果你需要更新原有集合中的数据,使用索引操作符来获得数据。
package main import "fmt" func main() { data := []int{1, 2, 3} for i, _ := range data { data[i] *= 10 } fmt.Println("data:", data) // 程序输出 data: [10 20 30] }
本书《Go语言四十二章经》内容在github上同步地址:https://github.com/ffhelicopter/Go42 本书《Go语言四十二章经》内容在简书同步地址: https://www.jianshu.com/nb/29056963
虽然本书中例子都经过实际运行,但难免出现错误和不足之处,烦请您指出;如有建议也欢迎交流。 联系邮箱:roteman@163.com
以上所述就是小编给大家介绍的《《Go语言四十二章经》第十三章 字典(Map)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 区块链技术语言(十九):Go语言字典
- 区块链技术语言(二十六):Go语言字典
- 语音识别语言模型和拼音字典文件制作
- 6. Go 语言数据类型:字典与布尔类型
- 6. Go语言中的字典与布尔类型
- Go语言学习笔记05--切片slice与字典map
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
屏幕上的聪明决策
Shlomo Benartzi、Jonah Lehrer / 石磊 / 北京联合出版公司 / 2017-3 / 56.90
为什么在手机上购物的人,常常高估商品的价值? 为什么利用网络订餐,人们更容易选择热量高的食物? 为什么网站上明明提供了所有选项,人们却还是选不到最佳的方案? 屏幕正在改变我们的思考方式,让我们变得更冲动,更容易根据直觉做出反应,进而做出错误的决策。在《屏幕上的聪明决策》一书中,什洛莫·贝纳茨教授通过引人入胜的实验及案例,揭示了究竟是什么影响了我们在屏幕上的决策。 ......一起来看看 《屏幕上的聪明决策》 这本书的介绍吧!