Go入门(9)——字典
Go中的map
类型,可以称作集合、字典,在其它编程语言也有称为hash
、hashTable
等。
概念
map
是引用类型,声明时不需要确定长度,可以动态增长。未初始化的map
值为nil
。
go var map1 map[keytype]valuetype
// 如:
var map1 map[string]int
键key
的类型必须是可以使用==
和!=
比较的类型,如string
、int
、float
,所以数组、切片、复杂结构体不能作为键(仅包含内建类型的struct
是可以作为键的,含有数组切片的struct
不得作为键)。另外,指针、接口类型可以作为键。若使用结构体作为键,可以使用Key()
和Hash()
方法,通过结构体的域计算出唯一的数字或字符串的键。
值value
可以为任意类型;通过使用空接口类型,可以存储任意值,但是使用这种类型作为值时需要先进行类型断言。
map
是引用类型,内存使用make
分配。在每次构造map
时都应当使用make
。
存在性
val1, isPresent = map1[key1]
isPresent
返回bool
值,若key1
存在于map1
,则val1
就是key1
对应的值,且isPresent
为true
;否则val1
为空值,isPresent
为false
。
删除
Go中封装了delete
方法,操作简便。如果键不存在,该操作不会产生报错。
package main
import "fmt"
func main(){
var value int
var isPresent bool
map1 := make(map[string]int)
map1["New Delhi"] = 55
map1["Beijing"] = 20
map1["Washington"] = 25
value, isPresent = map1["Beijing"]
if isPresent {
fmt.Printf("The value of \"Beijing\" in map1 is: %d\n", value)
} else {
fmt.Printf("map1 does not contain Beijing")
}
value, isPresent = map1["Paris"]
fmt.Printf("Is \"Paris\" in map1 ?: %t\n", isPresent)
fmt.Printf("Value is: %d\n", value)
// delete an item:
delete(map1, "Washington")
value, isPresent = map1["Washington"]
if isPresent {
fmt.Printf("The value of \"Washington\" in map1 is: %d\n", value)
} else {
fmt.Println("map1 does not contain Washington")
}
}
输出为:
The value of "Beijing" in map1 is: 20
Is "Paris" in map1 ?: false
Value is: 0
map1 does not contain Washington
遍历
for key, value := range map1 {
// ...
}
key
、value
都是局部变量。
如果只需要获取键,可以如下使用:
for key := range map1 {
fmt.Printf("key is: %d\n", key)
}
排序
map
默认是无序的。如果需要对map
进行排序,需要将键或者值拷贝到一个切片,再对切片进行排序,最后根据切片使用for-range
得到排序后的map
。
// the telephone alphabet:
package main
import (
"fmt"
"sort"
)
var (
barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
"delta": 87, "echo": 56, "foxtrot": 12,
"golf": 34, "hotel": 16, "indio": 87,
"juliet": 65, "kili": 43, "lima": 98}
)
func main() {
fmt.Println("unsorted:")
for k, v := range barVal {
fmt.Printf("Key: %v, Value: %v / ", k, v)
}
keys := make([]string, len(barVal))
i := 0
for k, _ := range barVal {
keys[i] = k
i++
}
sort.Strings(keys)
fmt.Println()
fmt.Println("sorted:")
for _, k := range keys {
fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
}
}
输出为:
unsorted:
Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: juliet, Value: 65 / Key: kili, Value: 43 / Key: lima, Value: 98 / Key: alpha, Value: 34 / Key: bravo, Value: 56 / Key: echo, Value: 56 / Key: hotel, Value: 16 / Key: indio, Value: 87 /
sorted:
Key: alpha, Value: 34 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: echo, Value: 56 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: hotel, Value: 16 / Key: indio, Value: 87 / Key: juliet, Value: 65 / Key: kili, Value: 43 / Key: lima, Value: 98 /
若使用结构体构造map
,则可以添加一个“下标”方便索引:
type name struct {
key string
value int
}