Contents
2.3. 字典¶
在业务和算法中需要使用任意类型的关联关系时,就需要使用到映射,如学号和学生的对应、名字与档案的对应等。
Go语言提供的映射关系容器为map。map使用散列表(hash)实现。
2.3.1. 1.添加关联到map并访问关联和数据¶
Go语言中map的定义是这样的:
map[keyType]ValueType
· KeyType为键类型
· ValueType为键对应的值类型
一个map的键和值总是成对出现的。
package main
import "fmt"
func main() {
// 创建一个map
scene := make(map[string]int)
// 向map中添加映射关系
scene["route"] = 66
fmt.Println(scene["route"]) //66
v := scene["route2"]
fmt.Println(v) //0
}
另外一种声明map的方式
m := map[string]string{
"name": "hujianli",
"age": "22",
"sex": "man",
"school": "dianda",
}
// name:hujianli age:22 sex:man school:dianda
fmt.Printf("name:%s age:%s sex:%s school:%s", m["name"], m["age"], m["sex"], m["school"])
某些情况下,需要明确知道查询中某个键是否在map中存在,可以使用一种特殊的写法来实现.
看下面的代码:
v, ok := scene["route"]
例如,如果元素类型是一个数字,你可以需要区分一个已经存在的0,和不存在而返回零值的0,可以像下面这样测试:
age, ok := ages["bob"]
if !ok { /* "bob" is not a key in this map; age == 0. */ }
你会经常看到将这两个结合起来使用,像这样:
if age, ok := ages["bob"]; !ok { /* ... */ }
示例
package main
import "fmt"
func main() {
// var mydicMap map[string]string
mydicMaps := make(map[string]string)
mydicMaps["hujianli1"] = "A1"
mydicMaps["hujianli2"] = "A2"
mydicMaps["hujianli3"] = "A3"
for k, v := range mydicMaps {
fmt.Printf("%s %s\n", k, v)
}
name1, ok := mydicMaps["hu1"]
if !ok {
fmt.Println("----------", name1)
}
// 或者
if name2, ok := mydicMaps["hu2"]; !ok {
fmt.Println("----------", name2)
}
}
2.3.2. 2.遍历map中的键值对–访问关联关系¶
m := map[string]string{
"name": "hujianli",
"age": "22",
"sex": "man",
"school": "dianda",
}
for i, i2 := range m {
fmt.Printf("key:%s value:%s\n", i, i2)
}
// 只遍历值
for _, i2 := range m {
fmt.Printf("%s\n", i2)
}
// 只遍历键
for i := range m {
fmt.Printf("%s\n", i)
}
如果要特定顺序的遍历结果。正确的做法是排序
2.1 排序遍历¶
package main
import (
"fmt"
"sort"
)
func main() {
scene := make(map[string]int)
//准备map数据
scene["route"] = 66
scene["brazil"] = 4
scene["china"] = 960
// 声明一个切片保存map数据
var sceneList []string
// 将map数据遍历后复制到切片中
for key := range scene {
sceneList = append(sceneList,key)
}
// 对切片进行排序
sort.Strings(sceneList)
// 输出
fmt.Println(sceneList) //[brazil china route]
}
2.3.3. 3.使用delete()函数从map中删除键值对¶
delete函数从map中删除一组键值对,delete函数的格式如下:
delete(map,键)
· map为要删除的map实例
· 键为要删除map键值对中的键
package main
import "fmt"
func main() {
scene := make(map[string]int)
//准备map数据
scene["route"] = 66
scene["brazil"] = 4
scene["china"] = 960
// 删除一个键
delete(scene, "brazil")
fmt.Println(scene) //map[china:960 route:66]
for i, i2 := range scene {
fmt.Println(i,i2)
}
}
2.3.4. 4.清空map中的所有元素¶
Go 语言中没有清空map的方法和函数。清空map的位于方法是重新make一个新的map。 Go中的并行垃圾回收效率比写一个清空函数高效多了。
2.3.5. 5.能够在并发环境中使用的map-sync.Map¶
package main
import (
"fmt"
"sync"
)
func main() {
var scene sync.Map
// 将键值对保存到sync.Map中
scene.Store("green", 97)
scene.Store("red", 100)
scene.Store("blue", 200)
// 从sync.Map中根据键取值
scene.Load("red")
//根据键删除对应的键值对
scene.Delete("green")
// 遍历所有的键值对
scene.Range(func(key, value interface{}) bool {
fmt.Println("iterate:", key, value)
return true
})
}
/*
iterate: red 100
iterate: blue 200
*/
package main
import (
"fmt"
)
var opMap = func(name map[string]int) {
for key, value := range name {
fmt.Println(key, value)
}
name["Life"] = 100
if value, ok := name["Go"]; ok {
fmt.Println(value)
} else {
fmt.Println("no exists Go")
}
delete(name, "java")
}
func main() {
nameMap := make(map[string]int)
nameMap["java"] = 200
nameMap["php"] = 100
nameMap["python"] = 180
nameMap["js"] = 220
opMap(nameMap)
fmt.Println(nameMap)
}
2.3.6. 6.在函数间传递映射¶
在函数间传递映射并不会制造出该映射的一个副本。实际上,当传递映射给一个函数,并对这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改。
package main
import "fmt"
func main() {
// 创建一个映射,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"AliceBlue": "#f0f8ff",
"Coral": "#ff7F50",
"DarkGray": "#a9a9a9",
"ForestGreen": "#228b22",
}
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("key is: %s value is: %s\n", key, value)
}
fmt.Println("--------------------------------------------------")
// 调用函数来移除指定的键
removeColor(colors, "Coral")
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
}
func removeColor(colors map[string]string, s string) {
delete(colors, s)
}
/**
key is: AliceBlue value is: #f0f8ff
key is: Coral value is: #ff7F50
key is: DarkGray value is: #a9a9a9
key is: ForestGreen value is: #228b22
--------------------------------------------------
Key: DarkGray Value: #a9a9a9
Key: ForestGreen Value: #228b22
Key: AliceBlue Value: #f0f8ff
*/
2.3.7. 7.使用map查找重复的行¶
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
counts := make(map[string]int)
for _, filename := range os.Args[1:] {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
continue
}
for _, line := range strings.Split(string(data), "\n") {
counts[line]++
}
}
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
ReadFile函数返回byte类型的slice,这个slice必须被转换为string,之后才能够用strings.Split方法来进行处理。