前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang中map基础

Golang中map基础

作者头像
周小末天天开心
发布2023-10-16 12:22:01
1030
发布2023-10-16 12:22:01
举报

map类型

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

声明和初始化

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

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

代码语言:javascript
复制
var m map[string]int  // 声明一个map变量m
m = make(map[string]int)  // 使用make函数创建一个map对象

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

代码语言:javascript
复制
m := map[string]int{
    "apple": 1, 
    "banana": 2,
}

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

代码语言:javascript
复制
m := make(map[string]int, 10)  // 初始化容量为10的map

元素操作

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

(1)添加或修改元素

代码语言:javascript
复制
m["peach"] = 3  // 添加单个元素
m["banana"] = 4  // 修改单个元素

(2)删除元素

代码语言:javascript
复制
delete(m, "banana")  // 删除单个元素

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

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

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

代码语言:javascript
复制
for k, v := range m {
    fmt.Printf("%s -> %d\n", k, v)
}

(5)清空map

代码语言:javascript
复制
for k := range m {
    delete(m, k)
}

大小和容量

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

代码语言:javascript
复制
length := len(m)

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

代码语言:javascript
复制
m := make(map[string]int, 16) // 初始化容量为16的map

并发问题

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

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

代码语言:javascript
复制
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产生影响。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • map类型
    • 声明和初始化
      • 元素操作
        • 大小和容量
          • 并发问题
            • 实现原理
              • 注意
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档