编程 Go/Golang中的集合 – 使用映射和推荐的包

2024-11-19 02:03:38 +0800 CST views 812

Go/Golang中的集合 – 使用映射和推荐的包

Go 语言没有原生的集合类型,标准库也没有提供相应功能。那么,如何在 Go 中创建集合呢?

使用映射

首先,我们可以使用映射来实现集合。映射通过键值对的形式存储数据,其中键需要是可比较类型。因此,映射的键本质上形成了一个集合。

示例:

x := map[string]struct{}{}

在此映射中,键为 string 类型,值为空结构体 struct{}。由于空结构体不占用内存,它是实现集合的一种高效方法。

初始化集合

可以通过为映射的键初始化来创建集合,并将值设为空结构体。例如:

set := map[string]struct{}{
    "foo": {},
    "bar": {},
}

向集合添加元素

通过将键设置为空结构体来添加元素:

set["foo"] = struct{}{}

从集合中移除元素

使用 delete 函数移除集合中的元素:

delete(set, "bar")

检查元素是否存在

使用索引表达式可以检查集合中是否存在某个元素:

_, ok := set["foo"]
if ok {
    fmt.Println("foo exists in the set")
}

集合的大小(基数)

使用内置的 len 函数来获取集合的大小:

size := len(set)

列出集合中的元素

使用 for 循环遍历集合中的元素:

for element := range set {
    fmt.Println(element)
}

并发

映射在 Go 中并不是并发安全的。如果多个 goroutine 访问同一个映射,你需要使用互斥锁或者通道来协调访问。

使用第三方包实现集合

如果你的程序大量依赖集合操作,可以考虑使用开源包,如 deckarep/golang-set。它提供了更丰富的集合功能,如差集、交集等。

示例:

s1 := mapset.NewSet("a", "b", "c")
s2 := mapset.NewSet("c", "d", "e")
intersection := s1.Intersect(s2)
fmt.Println(intersection) // 输出: Set{c}

JSON 转换

deckarep/golang-set 提供了对 encoding/json 包的支持,可以轻松地将集合转换为 JSON 数组。

并发支持

deckarep/golang-set 返回的集合是并发安全的,它使用读写互斥锁来协调并发访问。如果并发开销较大,还可以选择非线程安全的构造函数 NewThreadUnsafeSet

不可比较类型的集合

Go 中某些类型,如函数、映射和切片,不能直接用于集合,因为它们不能使用 == 进行比较。如果要将这些类型用于集合,需要选择一个可比较的替代类型来作为键。例如,对于 time.Time 类型,可以使用 UTC 格式的字符串或 UNIX 时间戳来表示。

总结

  • Go 没有原生的集合类型,可以使用映射来实现集合。
  • 使用空结构体 struct{} 作为映射的值可以节省内存。
  • 并发访问映射时需使用互斥锁或通道。
  • deckarep/golang-set 提供了更丰富的集合操作,如交集、差集、并集等。
  • 使用不可比较类型作为集合元素时需要额外处理。

希望这篇文章对你有所帮助!如果感兴趣,可以订阅更多相关内容。

参考链接:

推荐文章

H5抖音商城小黄车购物系统
2024-11-19 08:04:29 +0800 CST
Vue3中如何进行异步组件的加载?
2024-11-17 04:29:53 +0800 CST
Vue3中如何处理SEO优化?
2024-11-17 08:01:47 +0800 CST
H5端向App端通信(Uniapp 必会)
2025-02-20 10:32:26 +0800 CST
PHP来做一个短网址(短链接)服务
2024-11-17 22:18:37 +0800 CST
一个收银台的HTML
2025-01-17 16:15:32 +0800 CST
使用Python实现邮件自动化
2024-11-18 20:18:14 +0800 CST
宝塔面板 Nginx 服务管理命令
2024-11-18 17:26:26 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
PHP 8.4 中的新数组函数
2024-11-19 08:33:52 +0800 CST
html一些比较人使用的技巧和代码
2024-11-17 05:05:01 +0800 CST
Golang 几种使用 Channel 的错误姿势
2024-11-19 01:42:18 +0800 CST
Go 协程上下文切换的代价
2024-11-19 09:32:28 +0800 CST
ElasticSearch集群搭建指南
2024-11-19 02:31:21 +0800 CST
JavaScript设计模式:组合模式
2024-11-18 11:14:46 +0800 CST
Vue3中的组件通信方式有哪些?
2024-11-17 04:17:57 +0800 CST
Vue 3 是如何实现更好的性能的?
2024-11-19 09:06:25 +0800 CST
如何在 Linux 系统上安装字体
2025-02-27 09:23:03 +0800 CST
程序员茄子在线接单