Go 语言之 Maps 详解:创建、遍历、操作和注意事项

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
注册配置 MSE Nacos/ZooKeeper,118元/月
性能测试 PTS,5000VUM额度
简介: Maps用于以键值对的形式存储数据值。Maps中的每个元素都是一个键值对。Maps是一个无序且可更改的集合,不允许重复。Maps的长度是其元素的数量。您可以使用 len() 函数来查找长度。Maps的默认值是 nil。Maps保存对底层哈希表的引用。

Maps用于以键值对的形式存储数据值。Maps中的每个元素都是一个键值对。Maps是一个无序且可更改的集合,不允许重复。Maps的长度是其元素的数量。您可以使用 len() 函数来查找长度。Maps的默认值是 nil。Maps保存对底层哈希表的引用。

Go语言有多种方法来创建Maps。

使用 var 和 := 语法创建Maps

var a = map[KeyType]ValueType{
   key1:value1, key2:value2,...}
b := map[KeyType]ValueType{
   key1:value1, key2:value2,...}

示例

以下示例展示了如何在Go中创建Maps。请注意代码中和输出中的顺序。

package main
import ("fmt")

func main() {
      
  var a = map[string]string{
   "brand": "Ford", "model": "Mustang", "year": "1964"}   
  b := map[string]int{
   "Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4}

  fmt.Printf("a\t%v\n", a)   
  fmt.Printf("b\t%v\n", b)
}

结果:

a   map[brand:Ford model:Mustang year:1964]
b   map[Bergen:2 Oslo:1 Stavanger:4 Trondheim:3]

注意:代码中定义的Maps元素的顺序与它们存储的方式不同。数据以一种能够从Maps中高效检索数据的方式存储。

使用 make() 函数创建Maps

var a = make(map[KeyType]ValueType)
b := make(map[KeyType]ValueType)

示例

以下示例展示了如何使用 make() 函数在Go中创建Maps。

package main
import ("fmt")

func main() {
      
  var a = make(map[string]string) // Maps 现在为空   
  a["brand"] = "Ford"
  a["model"] = "Mustang"
  a["year"] = "1964"
                                 // a 不再为空   
  b := make(map[string]int)   
  b["Oslo"] = 1   
  b["Bergen"] = 2   
  b["Trondheim"] = 3   
  b["Stavanger"] = 4

  fmt.Printf("a\t%v\n", a)   
  fmt.Printf("b\t%v\n", b)
}

结果:

a   map[brand:Ford model:Mustang year:1964]
b   map[Bergen:2 Oslo:1 Stavanger:4 Trondheim:3]

创建一个空Maps

创建空Maps有两种方式。一种是使用 make() 函数,另一种是使用以下语法。

var a map[KeyType]ValueType

注意:使用 make() 函数是创建空Maps的正确方式。如果以不同的方式创建空Maps并写入它,将会引发运行时错误。

示例

以下示例演示了使用 make() 函数和不使用 make() 函数声明空Maps的区别。

package main
import ("fmt")

func main() {
      
  var a = make(map[string]string)   
  var b map[string]string

  fmt.Println(a == nil)   
  fmt.Println(b == nil)
}

结果:

false
true

允许的键类型

Maps键可以是任何定义了等号运算符(==)的数据类型,包括:

  • 布尔值
  • 数字
  • 字符串
  • 数组
  • 指针
  • 结构体
  • 接口(只要动态类型支持等号运算)

不允许的键类型包括:

  • 切片
  • Maps
  • 函数

这些类型是不允许的,因为它们不支持等号运算(==)。

允许的值类型

Maps的值可以是任何类型。

访问Maps元素

您可以通过以下方式访问Maps元素:

value = map_name[key]

示例

以下示例演示了如何访问Maps元素。

package main
import ("fmt")

func main() {
      
  var a = make(map[string]string)   
  a["brand"] = "Ford"
  a["model"] = "Mustang"
  a["year"] = "1964"

  fmt.Printf(a["brand"])
}

结果:

Ford

更新和添加Maps元素

要更新或添加元素,可以使用以下方式:

map_name[key] = value

示例

以下示例演示了如何更新和添加元素到Maps中。

package main
import ("fmt")

func main() {
      
  var a = make(map[string]string)   
  a["brand"] = "Ford"
  a["model"] = "Mustang"
  a["year"] = "1964"

  fmt.Println(a)

  a["year"] = "1970" // 更新元素   
  a["color"] = "red" // 添加元素

  fmt.Println(a)
}

结果:

map[brand:Ford model:Mustang year:1964]
map[brand:Ford color:red model:Mustang year:1970]

从Maps中删除元素删除元素使用delete()函数。

语法

delete(map_name, key)

示例

package main
import ("fmt")

func main() {
   
  var a = make(map[string]string)
  a["brand"] = "Ford"
  a["model"] = "Mustang"
  a["year"] = "1964"

  fmt.Println(a)

  delete(a, "year")

  fmt.Println(a)
}

结果

map[brand:Ford model:Mustang year:1964] map[brand:Ford model:Mustang]

检查Maps中特定元素的存在 您可以使用以下语法检查Maps中是否存在特定键:

语法 val, ok := map_name[key]

如果只想检查特定键的存在,可以在val的位置使用下划线(_)。

示例

package main
import ("fmt")

func main() {
   
  var a = map[string]string{
   "brand": "Ford", "model": "Mustang", "year": "1964", "day": ""}

  val1, ok1 := a["brand"] // 检查现有键及其值
  val2, ok2 := a["color"] // 检查不存在的键及其值
  val3, ok3 := a["day"]   // 检查现有键及其值
  _, ok4 := a["model"]    // 仅检查存在的键而不检查其值

  fmt.Println(val1, ok1)
  fmt.Println(val2, ok2)
  fmt.Println(val3, ok3)
  fmt.Println(ok4)
}

结果

Ford true  false  true true

Maps是引用 Maps是对哈希表的引用。

如果两个Maps变量引用同一个哈希表,则更改一个变量的内容会影响另一个变量的内容。

示例

package main
import ("fmt")

func main() {
   
  var a = map[string]string{
   "brand": "Ford", "model": "Mustang", "year": "1964"}
  b := a

  fmt.Println(a)
  fmt.Println(b)

  b["year"] = "1970"
  fmt.Println("更改b后:")

  fmt.Println(a)
  fmt.Println(b)
}

结果

map[brand:Ford model:Mustang year:1964] map[brand:Ford model:Mustang year:1964]
更改b后:
map[brand:Ford model:Mustang year:1970] map[brand:Ford model:Mustang year:1970]

**遍历Maps **您可以使用range来遍历Maps。

示例 以下示例显示了如何遍历Maps中的元素。请注意输出中元素的顺序。

package main
import ("fmt")

func main() {
   
  a := map[string]int{
   "one": 1, "two": 2, "three": 3, "four": 4}

  for k, v := range a {
   
    fmt.Printf("%v : %v, ", k, v)
  }
}

结果

two : 2, three : 3, four : 4, one : 1,

按特定顺序遍历Maps。Maps是无序的数据结构。如果需要按特定顺序遍历Maps,则必须使用单独的数据结构来指定该顺序。

示例 以下示例演示了如何按特定顺序遍历Maps中的元素。

package main
import ("fmt")

func main() {
   
  a := map[string]int{
   "one": 1, "two": 2, "three": 3, "four": 4}

  var b []string // 定义顺序
  b = append(b, "one", "two", "three", "four")

  for k, v := range a {
    // 无序循环
    fmt.Printf("%v : %v, ", k, v)
  }

  fmt.Println()

  for _, element := range b {
    // 使用定义的顺序循环
    fmt.Printf("%v : %v, ", element, a[element])
  }
}

结果

two : 2, three : 3, four : 4, one : 1,
one : 1, two : 2, three : 3, four : 4,

最后

为了方便其他设备和平台的小伙伴观看往期文章:

微信公众号搜索:Let us Coding,关注后即可获取最新文章推送

看完如果觉得有帮助,欢迎 点赞、收藏、关注

相关文章
|
4天前
|
存储 监控 算法
探秘员工泄密行为防线:基于Go语言的布隆过滤器算法解析
在信息爆炸时代,员工泄密行为对企业构成重大威胁。本文聚焦布隆过滤器(Bloom Filter)这一高效数据结构,结合Go语言实现算法,帮助企业识别和预防泄密风险。通过构建正常操作“指纹库”,实时监测员工操作,快速筛查可疑行为。示例代码展示了如何利用布隆过滤器检测异常操作,并提出优化建议,如调整参数、结合日志分析系统等,全方位筑牢企业信息安全防线,守护核心竞争力。
|
5天前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
54 20
|
11天前
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
20 0
|
12天前
|
Go C语言
Go语言入门:分支结构
本文介绍了Go语言中的条件语句,包括`if...else`、`if...else if`和`switch`结构,并通过多个练习详细解释了它们的用法。`if...else`用于简单的条件判断;`if...else if`处理多条件分支;`switch`则适用于基于不同值的选择逻辑。特别地,文章还介绍了`fallthrough`关键字,用于优化重复代码。通过实例如判断年龄、奇偶数、公交乘车及成绩等级等,帮助读者更好地理解和应用这些结构。
34 14
|
26天前
|
存储 监控 算法
内网监控系统之 Go 语言布隆过滤器算法深度剖析
在数字化时代,内网监控系统对企业和组织的信息安全至关重要。布隆过滤器(Bloom Filter)作为一种高效的数据结构,能够快速判断元素是否存在于集合中,适用于内网监控中的恶意IP和违规域名筛选。本文介绍其原理、优势及Go语言实现,提升系统性能与响应速度,保障信息安全。
28 5
|
Go
golang遍历返回全部目录不返回具体的文件名
使用参考: d := dir.NewDir("/") dirs, err := d.LoopLevelDir(0) // 实现遍历目录的功能// 也可以指定层级遍历,遍历几层目录package dir import ( "fmt" "io/ioutil" "strings" "time" ) t...
931 0
|
1月前
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
|
1月前
|
算法 安全 Go
Go语言中的加密和解密是如何实现的?
Go语言通过标准库中的`crypto`包提供丰富的加密和解密功能,包括对称加密(如AES)、非对称加密(如RSA、ECDSA)及散列函数(如SHA256)。`encoding/base64`包则用于Base64编码与解码。开发者可根据需求选择合适的算法和密钥,使用这些包进行加密操作。示例代码展示了如何使用`crypto/aes`包实现对称加密。加密和解密操作涉及敏感数据处理,需格外注意安全性。
47 14
|
1月前
|
Go 数据库
Go语言中的包(package)是如何组织的?
在Go语言中,包是代码组织和管理的基本单元,用于集合相关函数、类型和变量,便于复用和维护。包通过目录结构、文件命名、初始化函数(`init`)及导出规则来管理命名空间和依赖关系。合理的包组织能提高代码的可读性、可维护性和可复用性,减少耦合度。例如,`stringutils`包提供字符串处理函数,主程序导入使用这些函数,使代码结构清晰易懂。
98 11
|
1月前
|
监控 安全 算法
深度剖析核心科技:Go 语言赋能局域网管理监控软件进阶之旅
在局域网管理监控中,跳表作为一种高效的数据结构,能显著提升流量索引和查询效率。基于Go语言的跳表实现,通过随机化索引层生成、插入和搜索功能,在高并发场景下展现卓越性能。跳表将查询时间复杂度优化至O(log n),助力实时监控异常流量,保障网络安全与稳定。示例代码展示了其在实际应用中的精妙之处。
44 9