Golang中map基础

简介: Golang中map基础

map类型


Go语言中的map类型是一种key-value(键值对)结构,用于存储一组无序的数据,其中键是唯一的,值可以相同或者不同。在Go语言的程序开发中,map使用广泛,尤其是用于缓存、关联数据等场景下。


声明和初始化


声明和初始化map的方式有三种:

(1)声明变量后使用make函数创建map

var m map[string]int  // 声明一个map变量m
m = make(map[string]int)  // 使用make函数创建一个map对象


(2)使用字面量方式创建map

1. m := map[string]int{
2. "apple": 1, 
3. "banana": 2,
4. }

(3)使用make函数创建map同时初始化

m := make(map[string]int, 10)  // 初始化容量为10的map


元素操作


map中的元素是键值对(key-value)的形式存储的,其中键必须是支持==比较运算符的类型,如string、数字类型、char等;值可以是任意类型。map中常用的元素操作有:

(1)添加或修改元素


m["peach"] = 3  // 添加单个元素
m["banana"] = 4  // 修改单个元素

(2)删除元素

delete(m, "banana")  // 删除单个元素

(3)获取元素及判断元素是否存在

v, ok := m["peach"]  // 获取单个元素
if ok {
    fmt.Println(v)
}
// 或者使用下面的方式判断元素是否存在
if _, ok := m["banana"]; ok {
    fmt.Println("banana is exist")
}

(4)遍历map中的所有元素

for k, v := range m {
    fmt.Printf("%s -> %d\n", k, v)
}

(5)清空map

1. for k := range m {
2. delete(m, k)
3. }


大小和容量

map的长度(长度表示map元素的个数),可以通过len()函数获得

length := len(m)


map的容量(容量表示map底层的哈希表容量),不能改变,只能通过make函数初始化时设置容量

m := make(map[string]int, 16) // 初始化容量为16的map


并发问题


map不是线程安全的,多个goroutine同时对同一个map进行读写操作,会产生竞态条件,导致程序运行异常。

解决map的并发问题,可以使用sync包提供的锁机制进行同步,例如:


import "sync"
var mu sync.Mutex  // 创建一个互斥锁
// goroutine1
mu.Lock()  // 上锁
m["apple"] = 1
mu.Unlock()  // 解锁
// goroutine2
mu.Lock()  // 上锁
v, _ := m["apple"]
fmt.Println(v)
mu.Unlock()  // 解锁


实现原理


map底层是基于哈希表实现的,map使用哈希表来存储键值对,通过哈希函数将键映射为哈希值,用哈希值作为数组的下标,将值储存在以哈希值为下标的数组槽中。但是,哈希函数并不是绝对可靠的,如果两个不同的键映射为同一个哈希值,这个情况被称为哈希冲突。


解决哈希冲突一般有以下两种方法:


(1)链表法


将哈希值相同的键值对附加到同一个链表上,这个链表通常被称为buckets。当键值对数量较少时,链表法是一种非常有效的解决哈希冲突的方法。


(2)开放地址法


开放地址法有三种常见的实现方式:线性探测法、二次探测法和双重散列法。开放地址法的主要思想是:当出现冲突时,顺序,直到找到一个空闲的槽位为止。


注意


Map的元素遍历顺序:Map的元素遍历顺序是随机的,不保证元素的顺序


Map的key类型:Map的key可以是任意可比较类型,如整数、浮点数、字符串、数组、结构体等,但不可以是切片、函数、Map等不可比较类型


Map的value类型:Map的value可以是任意类型,包括切片、函数、Map等复杂类型。


Map的值传递:Map在函数参数传递时是按引用传递的,即修改传入的Map会对原Map产生影响。

相关文章
|
6月前
|
存储 Go
Golang底层原理剖析之map
Golang底层原理剖析之map
60 1
|
6月前
|
存储 Go 容器
【golang】对键值有顺序要求时,不要使用 map
【golang】对键值有顺序要求时,不要使用 map
119 0
|
6月前
|
缓存 安全 Go
浅谈Golang线程安全的sync.Map
浅谈Golang线程安全的sync.Map
81 0
|
安全 Cloud Native Go
需要提醒你关于 golang 中 map 使用的几点注意事项
需要提醒你关于 golang 中 map 使用的几点注意事项
|
2月前
|
Go
Golang语言之映射(map)快速入门篇
这篇文章是关于Go语言中映射(map)的快速入门教程,涵盖了map的定义、创建方式、基本操作如增删改查、遍历、嵌套map的使用以及相关练习题。
36 5
|
3月前
|
Java Serverless Go
Golang 开发函数计算问题之在 Golang 中避免 "concurrent map writes" 异常如何解决
Golang 开发函数计算问题之在 Golang 中避免 "concurrent map writes" 异常如何解决
|
5月前
|
Go
GOLANG MAP 查找
GOLANG MAP 查找
|
5月前
|
存储 Go 索引
GOLANG MAP 底层实现
GOLANG MAP 底层实现
|
6月前
|
存储 编译器 Go
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
【4月更文挑战第21天】Go语言中的`map`提供快速的键值对操作,包括初始化、增删查改和遍历。初始化时,推荐使用`make()`函数,如`make(map[string]int)`。插入和查询键值对直接通过索引访问,更新则重新赋值。删除键值对需用`delete()`函数,确保键存在。遍历map常用`for range`,注意避免在遍历中修改map。了解这些并避免易错点,能提升代码效率和可读性。
116 1
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
|
6月前
|
存储 缓存 安全
Golang深入浅出之-Go语言中的并发安全容器:sync.Map与sync.Pool
Go语言中的`sync.Map`和`sync.Pool`是并发安全的容器。`sync.Map`提供并发安全的键值对存储,适合快速读取和少写入的情况。注意不要直接遍历Map,应使用`Range`方法。`sync.Pool`是对象池,用于缓存可重用对象,减少内存分配。使用时需注意对象生命周期管理和容量控制。在多goroutine环境下,这两个容器能提高性能和稳定性,但需根据场景谨慎使用,避免不当操作导致的问题。
192 7