1.字典的键类型不能是哪些类型?
- Go 语言字典的键类型不可以是函数类型、字典类型和切片类型
- 如果键的类型是接口类型的,那么键值的实际类型也不能是上述三种类型
- 如果键的类型是数组类型,那么还要确保该类型的元素类型不是函数类型、字典类型 或切片类型
注意:Go 语言规范规定,在键类型的值之间必须可以施加操作符==和!=。
2.在字典中如何查找键值?
首先,每个哈希桶都会把自己包含的所有键的哈希值存起来。Go 语言会用被查找键的哈希值与 这些哈希值逐个对比,看看是否有相等的。如果一个相等的都没有,那么就说明这个桶中没有要 查找的键值,这时 Go 语言就会立刻返回结果了。如果有相等的,那就再用键值本身去对比一次。为什么还要对比?原因是:不同值的哈希值是可能相同的。这有个术语,叫做“哈希碰撞”。所以,即使哈希值一样,键值也不一定一样。如果键类型的值之间无法判断相等,那么此时这个映射的过程就没办法继续下去了。最后,只有键的哈希值和键值都相等,才能说明查找到了匹配的键 - 元素对。
3.优先考虑哪些类型作为字典的键类型?
答:优先选择数值类型和指针类型,通常情况下类型的宽度(类型的宽度是指单个值需要占用的字节数)越小越好,如果非要选择字符串类型则最好对键值的长度进行额外的约束。
4.在值为nil的字典上执行读操作会能成功吗,那写操作呢?
答:由于字典是引用类型,所以当程序中仅声明而不初始化一个字典类型的变量时,它的值是nil。除了添加键-元素对外,在一个值为nil的字典上做任何操作都不会引起错误。当在一个值为nil的字典中添加键-元素对时Go语言在运行时会立即抛出一个panic。
下面是一个demo程序:
package main
import "fmt"
func main() {
var m map[string]int
key := "two"
elem, ok := m["two"]
fmt.Printf("The element paired with key %q in nil map: %d (%v)\n",
key, elem, ok)
fmt.Printf("The length of nil map: %d\n",
len(m))
fmt.Printf("Delete the key-element pair by key %q...\n",
key)
delete(m, key)
elem = 2
fmt.Println("Add a key-element pair to a nil map...")
// 这里会引发panic。
m["two"] = elem
}
本节示例代码地址:demo Github