GO 之MAP的使用

简介:

    哈希表是计算机科学中最重要的数据结构之一。许多哈希表的实现有着千差万别的特性,但是总体上他们都提供了快速查询,添加和删除功能。go语言提供了内置数据类型map。

    映射是一种内置的数据结构,用来保存键值对的无序集合。

    map的声明格式如下:

        1、map[KeyType] ValueType

        KeyType类型必须是可以比较的,而ValueType可以是任意类型,甚至是另一个map

        2、以下这个m是一个键值为string,值为int的哈希表:var m map[string]int

        3、哈希表类型是引用类型,像指针或者切片m指向的值是nil;它没有指向一个初始化了的哈希表。一个nil哈希表在读的时候,像一个空的哈希表,但是尝试向m中写数据会引发一个运行时panic,所以别那样做。 使用内置函数make初始化一个哈希表

        m = make(map[string]int)//make函数申请并初始化了一个哈希表的数据结构并且返回一个指向这个初始化好了的哈希表

映射的创建:

        1、make(map[KeyType]ValueType,initialCapacity)

        2、make(map[KeyType]ValueType)

        3、map[KeyType]ValueType{}

        4、map[KeyType]ValueType{key1:value1,key2:value2.....,keyN:valueN}

egg:

package main
import "fmt"
func main() {
    map1 := make(map[string]string, 5)
    map2 := make(map[string]string)
    map3 := map[string]string{}
    map4 := map[string]string{"a": "1", "b": "2", "c": "3"}
    fmt.Println(map1, map2, map3, map4)
}

映射的填充和遍历

package main
import "fmt"
func main() {
    map1 := make(map[string]string)
    map1["a"] = "1"
    map1["b"] = "2"
    map1["c"] = "3"
    fmt.Println(map1)
    for key, value := range map1 {
        fmt.Printf("%s--->%s\n", key, value)
    }
}

##map是对key-value的遍历,直接操作value是值得拷贝,只有对key的操作才是修改value

package main
import "fmt"
func main() {
    sm := make([]map[int]string, 5)
    for _, value := range sm {
        value = make(map[int]string, 1)
        value[1] = "OK"
        fmt.Println(value)
    }
    fmt.Println(sm)
}

C:/Users/cherry/go/src/test/test.exe  [C:/Users/cherry/go/src/test]
map[1:OK]
map[1:OK]
map[1:OK]
map[1:OK]
map[1:OK]
[map[] map[] map[] map[] map[]]
值得拷贝操作
####
package main
import "fmt"
func main() {
    sm := make([]map[int]string, 5)
    for i := range sm {
        sm[i] = make(map[int]string, 1)
        sm[i][1] = "OK"
        fmt.Println(sm[i])
    }
    fmt.Println(sm)
}

映射的查找、修改和删除

package main
import "fmt"
func main() {
    map1 := map[string]string{"a": "1", "b": "2", "c": "3"}
    val, exist := map1["a"]  //
    val2, exist2 := map1["d"]
    fmt.Printf("%v,%v\n", exist, val)
    fmt.Printf("%v,%v\n", exist2, val2)
    map1["a"] = "9" //修改
    fmt.Printf("%v\n", map1)
    delete(map1, "b")\\删除
    fmt.Printf("%v\n", map1)
}

map指定key取对应的value时,可以指定返回两个值,第一个是对应的value,第二个是一个bool,表示是否有值。如上,"a"肯定有值,"b"肯定没值,修改映射和添加映射的操作没什么区别,若指定的键不存在则创建,否则,修改之


MAP并发:


哈希表在有并发的场景并不安全:同时读写一个哈希表的后果是不确定的。如果你需要使用goroutines同时对一个哈希表做读写,对哈希表的访问需要通过某种同步机制做协调。一个常用的方法是是使用 sync.RWMutex。

这个语句生命了一个counter变量,这是一个包含了一个map和sync.RWMutex的匿名结构体


##当map多层嵌套的时候,需要对它进行初始化操作,如:egg:

package main
import "fmt"
func main() {
    var m map[int]map[int]string
    m = make(map[int]map[int]string) //这里其实只对外层的map做了初始化操作
    a, ok := m[2][1]
    fmt.Println(a, ok)
    if !ok {
        m[2] = make(map[int]string)
    }
    m[2][1] = "Good1"
    a, ok = m[2][1]
    fmt.Println(a, ok)
}



本文转自 DBAspace 51CTO博客,原文链接:http://blog.51cto.com/dbaspace/1963134
相关文章
|
3月前
|
Go
Go 语言为什么不支持并发读写 map?
Go 语言为什么不支持并发读写 map?
|
2月前
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19
|
3月前
|
存储 算法 Java
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
|
3月前
|
存储 安全 NoSQL
Go map 读写性能优化 - 分片 map
Go map 读写性能优化 - 分片 map
45 1
|
3月前
|
存储 人工智能 安全
go sync.Map 设计与实现
go sync.Map 设计与实现
33 1
|
3月前
|
算法 安全 Go
go 语言中 map 的相关知识
go 语言中 map 的相关知识
|
3月前
|
存储 缓存 Go
如何检查 Go map 是否包含某个键?
【8月更文挑战第31天】
31 0
|
3月前
|
设计模式 安全 Java
Go - 使用 sync.Map 来解决 map 的并发操作问题
Go - 使用 sync.Map 来解决 map 的并发操作问题
36 1
|
3月前
|
存储 Go 容器
Go从入门到放弃之map(字典)
Go从入门到放弃之map(字典)
|
3月前
|
存储 Java 关系型数据库
听说过对 Go map 做 GC 吗?
听说过对 Go map 做 GC 吗?