Go基础|第4章:Map

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1043 次阅读

Golang.jpg

Synopsis: Go 语言里用映射用来处理具有键值对结构的数据,可以使用 map literal 或 make 函数来初始化映射。注意映射的零值为 nil,不能给它添加键值对,否则会报编译错误

1. 基础概念

映射(map) 可用来存储一系列 无序的键值对,无序的原因是映射的实现使用了散列表。它的每个 键必须唯一,只能是支持相等性判断的类型,比如数值、字符串、指针、接口、结构体或数组。切片、函数等类型具有引用语义,不能作为映射的键,否则会发生编译错误。映射的值可以是任何类型,比如切片也是可以的(比如 map[int][]string

与切片一样,映射也是引用类型。 若将映射传入函数中,并更改了该映射的内容,则此修改对函数的调用者同样可见

1.1 声明与初始化

(1) 映射字面量

可以使用 map literal 来初始化一个映射类型的对象:

package main

import "fmt"

func main() {
    m := map[string]int{
        "golang": 100,
        "python": 90,
    }
    //m := map[string]int{} // Empty map of string-int pairs
    fmt.Printf("%#v\n", m) // map[string]int{"golang":100, "python":90}
}

(2) make() 函数创建映射

package main

import "fmt"

func main() {
    m := make(map[string]int) // Empty map of string-int pairs
    //m :=make(map[string]int, 10) // Preallocate room for 10 entries
    m["golang"] = 100
    m["python"] = 90
    fmt.Printf("%#v\n", m) // map[string]int{"golang":100, "python":90}
}

注意: 映射类型的零值(zero value)是 nil,它和空映射的唯一区别是它不能新增键值对:

var m map[string]int // nil map of string-int pairs
m["golang"] = 100 // panic: assignment to entry in nil map

用内置函数 len() 可以获取映射的大小,即键值对的数目

1.2 增、删、改、查

对映射类型的键值对进行增、删、改是常量时间!

新增键值对:

m := make(map[string]int)
m["golang"] = 100
m["python"] = 90

判断键是否存在: 如果键存在,则 v 是它的值、ok 是 true; 如果键不存在,则 v 是值对应的类型的零值、ok 是 false:

v, ok := m["golang"]
fmt.Println(v, ok) // 100 true
v, ok = m["shell"]
fmt.Println(v, ok) // 0 false

所以推荐的做法是先判断键存不存在:

if v, ok := m["shell"]; ok {
    fmt.Println(v)
}

删除指定键值对,即使键不存在也是安全的:

delete(m, "golang")
delete(m, "shell")

1.3 迭代

键值对出现的顺序是不固定的。从 Go 1.12 版本开始,用 fmt 包(比如 fmt.Printf)来打印映射的内容时,默认已经按键排序了!

package main

import "fmt"

func main() {
    m := map[string]int{
        "golang":  100,
        "python":  90,
        "shell":   80,
        "node.js": 85,
    }
    fmt.Printf("%#v\n", m) // map[string]int{"golang":100, "python":90}

    for key, value := range m {
        fmt.Printf("Key: %v, value: %v\n", key, value)
    }
}

/* Output:
map[string]int{"golang":100, "node.js":85, "python":90, "shell":80}
Key: shell, value: 80
Key: node.js, value: 85
Key: golang, value: 100
Key: python, value: 90
*/

2. 在函数间传递映射

当传递映射给一个函数,并对这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改:

package main

import (
    "fmt"
)

func remove(m map[string]int, key string) {
    delete(m, key)
}

func main() {
    m := map[string]int{
        "golang":  100,
        "python":  90,
        "shell":   80,
        "node.js": 85,
    }

    for key, value := range m {
        fmt.Printf("Key: %v, value: %v\n", key, value)
    }

    remove(m, "python")
    fmt.Println()

    for key, value := range m {
        fmt.Printf("Key: %v, value: %v\n", key, value)
    }
}

/* Output:
Key: golang, value: 100
Key: python, value: 90
Key: shell, value: 80
Key: node.js, value: 85

Key: golang, value: 100
Key: shell, value: 80
Key: node.js, value: 85
*/

3. 获取键或值的切片

package main

import "fmt"

func main() {
    m := map[string]int{
        "golang":  100,
        "python":  90,
        "shell":   80,
        "node.js": 85,
    }
    keys := make([]string, 0, len(m))
    values := make([]int, 0, len(m))

    for k, v := range m {
        keys = append(keys, k)
        values = append(values, v)
    }

    fmt.Printf("%v len=%d cap=%d\n", keys, len(keys), cap(keys))       // [golang python shell node.js] len=4 cap=4
    fmt.Printf("%v len=%d cap=%d\n", values, len(values), cap(values)) // [100 90 80 85] len=4 cap=4
}

4. 通过键排序映射

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "golang":  100,
        "python":  90,
        "shell":   80,
        "node.js": 85,
    }

    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    fmt.Printf("%v len=%d cap=%d\n", keys, len(keys), cap(keys)) // [golang python shell node.js] len=4 cap=4

    sort.Strings(keys)
    fmt.Printf("%v len=%d cap=%d\n", keys, len(keys), cap(keys)) // [golang node.js python shell] len=4 cap=4

    for _, k := range keys {
        fmt.Printf("Key: %v, value: %v\n", k, m[k])
    }
}

/* Output:
[golang python shell node.js] len=4 cap=4
[golang node.js python shell] len=4 cap=4
Key: golang, value: 100
Key: node.js, value: 85
Key: python, value: 90
Key: shell, value: 80
*/
分类: Go 基础
标签: map make() golang
未经允许不得转载: LIFE & SHARE - 王颜公子 » Go基础|第4章:Map

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.