Go关键字--map

map

map关键字用来定义字典,其语法格式是:

map[key]value

从形式上看,有点怪异,中括号里边是字段的key值,value是key对应的值,通过key来查询value值,key与value之间形成关联关系。在字典中key值不能重复,value可以重复。

定义一个字典类型变量语法格式如下:

var 变量名 map[dataType]dataType
var 变量名 map[dataType]dataType = make(map[dataType]dataType) 
var 变量名 = make(map[dataType]dataType) 
var 变量名 map[dataType]dataType = map[dataType]dataType{}
var 变量名 = map[dataType]dataType{}
变量名 := map[dataType]dataType{}
变量名 := make(map[dataType]dataType)

下边来一段例子创建并初始化字典:

package main

import (
    "fmt"
)

func main() {

    // 定义字典类型变量的7种方法
    var rel map[string]string

    // 定义字典类型变量,并初始化
    var rela map[string]string = map[string]string{}

    // 定义字典类型变量,并初始化
    var relaa = map[string]string{}

    // 定义字典类型变量,并初始化
    var relb map[string]string = make(map[string]string)

    // 定义字典类型变量,并初始化
    var relbb = make(map[string]string)

    // 定义字典类型变量,并初始化
    relc := make(map[string]string)

    // 定义字典类型变量,并初始化
    relcc := map[string]string{}

    fmt.Println(rel, rela, relaa, relb, relbb, relc, relcc)
}

字典赋值

在给字典变量赋值之前,一定要初始化字典,初始化字典变量有两种方法,第一种是使用make关键字,第二种是使用map[dataType]dataType{}形式初始化:

var rel = make(map[string]string)
var relb = map[string]string{}

只有初始化完成之后,才能对字典类型变量进行赋值操作。

var rel map[string]string
rel = make(map[string]string)
// 中括号内的字符串 "a" 是key值, 赋值符号右边的 "1" 是key对应的value
rel["a"] = "1"

在給字典类型变量赋值或者查询值时,一定要初始化字典变量,否则会提示下边错误信息:

panic: assignment to entry in nil map

读取字典

读取字典,就是根据key值,在字典中查找key对应的value值,读取字典通常有两种方法,分别是:

// 第一种情况,断言查询
val,ok := map[key]

// 第二种情况直接查询
val := map[key]

上边两种读取字典的方法中,第一种采用断言的方式,当ok为true时,表示key存在于字典中,当ok为false时,表示key不存在于字典中。第二种情况直接查询key值的方式,如果key不在map种时,返回值是字典定义中value的类型默认初始值。如value的类型为int,则默认值为0,如果value类型是指针,则默认是nil,下边请看一段示例:

package main

import (
    "fmt"
)

func main() {
    // 定义字典,并初始化字典
    rel := map[string]int{
        "a": 1,
        "b": 2,
        "c": 3,
        "d": 4,
    }
    // 断言查询
    val, ok := rel["a"]
    fmt.Println("key 值是否存在:", ok, "key 对应的value是:", val)

    // 直接查询
    d := rel["b"]
    fmt.Println("key 对应的value是:", d)

    //断言查询不存在的key
    nval, yes := rel["abcd"]
    fmt.Println("key 值是否存在:", yes, "key 对应的value是:", nval)

    // 直接查询不存在的key
    nd := rel["abcd"]
    fmt.Println("key 对应的value是:", nd)
}

输出信息是:

key 值是否存在: true key 对应的value是: 1
key 对应的value是: 2
key 值是否存在: false key 对应的value是: 0
key 对应的value是: 0

从输出信息可以看出,当key值不在字典中时,返回的是key值对应value类型的初始值,在定义字典类型变量rel时,设定value的类型是int型,int初始值是0,当访问的key值为”abcd”时,由于”abcd”不存在于字典rel中,所以返回了int的默认值0。

并发不安全

golang的map在并发情况下访问是不安全的,也就是各个goroutine之间同时使用一个map类型变量时,如果有goroutine修改了map变量值,其他goroutine可能读取到脏数据的情况,如果要保持数据一致性,需要借助于读写锁。

在golang 1.9之后,sdk在sync包中提供了一个实现并发模式下安全的抽象类型,即sync.Map, 这个不是golang语法中的关键字,只是一个实现了并发安全的实现字典管理功能的结构体。sync.Map功能将会在标准库分析章节中进行介绍。在这里,需要记住一点,map类型变量是在并发下使用是不安全的,需要借助读写锁才能实现并发安全。

猜你喜欢

转载自blog.csdn.net/hzwy23/article/details/79999151
今日推荐