Go Map

Go Map
创建于:2020年08月14日 更新于:2020年08月23日

Go语言中 map 是一种特殊的数据结构,一种元素对(pair)的无序集合,pair 对应一个 key(索引)和一个 value(值),所以这个结构也称为关联数组或字典,这是一种能够快速寻找值的理想结构,给定 key,就可以迅速找到对应的 value。

map 是引用类型,可以使用如下方式声明:

var mapname map[keyType]valueType
  • mapname 为 map 变量名
  • keyType 为键类型
  • valueType 为键对应的值类型

在声明的时候不需要知道 map 的长度,因为 map 是可以动态增长的,未初始化的 map 的值是 nil,使用函数 len() 可以获取 map 中 pair 的数目。

映射的键可以是任何值。这个值的类型可以是内置的类型,也可以是结构类型,只要这个值可以使用==、!= 运算符做比较。切片、函数以及包含切片的结构类型这些类型由于具有引用语义,不能作为映射的键,使用这些类型会造成编译错误

package main
import "fmt"

func main() {
    var map1 map[string]int

    map1 = map[string]int{"one": 1, "two": 2}

    var map2 = make(map[string]int)

    map2 = map1

    // map也是一种引用类型,如果两个map同时指向一个底层,那么一个改变,另一个也相应改变。
    map2["two"] = 3

    fmt.Printf("Map1 is: %v\n", map1) // Map1 is: map[one:1 two:3]
    fmt.Printf("Map2 is: %v\n", map2) // Map2 is: map[one:1 two:3]
}

注意:可以使用 make(),但不能使用 new() 来构造 map,如果错误的使用 new() 分配了一个引用对象,会获得一个空引用的指针,相当于声明了一个未初始化的变量并且取了它的地址:

map2 := new(map[string]int)

接下来当我们调用 map2["two"] = 3 的时候,编译器会报错:

invalid operation: map2["two"] (type *map[string]int does not support indexing)

map遍历

package main
import "fmt"

func main() {
    var map1 map[string]int

    map1 = map[string]int{"one": 1, "two": 2, "three": 3}

    for key, val := range map1{

        fmt.Printf("key is: %v --- val is: %v\n", key, val)
    }

}

只遍历值可以使用_改为匿名变量的形式:

for _, val := range map{

只遍历键可以直接忽略值:

for key := range map{

map 是无序(存入的值和取出的值顺序不一定一致)的如果需要特定顺序的遍历结果,正确的做法是先排序

package main

import (
    "fmt"
    "sort"
)

func main() {
    var map1 map[string]int

    map1 = map[string]int{"one": 1, "two": 2, "three": 3}

    map1["a"] = 0
    map1["p"] = 4

    var slice1 []string

    for key := range map1{
        slice1 = append(slice1, key)
    }

    sort.Strings(slice1)
    fmt.Println(slice1) // [a one p three two]

}

删除元素

使用 delete() 内建函数从 map 中删除一组键值对,delete() 函数的格式如下:

delete(map, key)
package main

import (
    "fmt"
)

func main() {
    var map1 map[string]int

    map1 = map[string]int{"one": 1, "two": 2, "three": 3}

    delete(map1, "two")
    fmt.Printf("%v", map1) // map[one:1 three:3]

}

判断键是否存在

package main

import (
    "fmt"
)

func main() {
    var map1 map[string]int

    map1 = map[string]int{"one": 1, "two": 2, "three": 3}

    value, exist := map1["one"]
    // 键存在 exist 为true, 否则为 false

    fmt.Println(exist) // true
    if exist{
        fmt.Printf("%v", value)
    }


}