在 Go 语言中没有内建的 Set(集合) 类型,但我们可以通过
map
来模拟集合的功能,借助map[T]bool
或map[T]struct{}
实现高效的去重、添加、删除、判断元素是否存在等操作。
一、什么是集合?
集合(Set)是一种不包含重复元素的无序数据结构。典型操作包括:
- • 添加元素(Add)
- • 删除元素(Remove)
- • 判断是否存在(Contains)
- • 遍历集合(Iterate)
二、使用 map[T]bool
模拟 Set
set := make(map[string]bool)
// 添加元素
set["apple"] = true
set["banana"] = true
// 判断是否存在
if set["apple"] {
fmt.Println("apple 存在")
}
// 删除元素
delete(set, "banana")
// 遍历集合
for item := range set {
fmt.Println("元素:", item)
}
这种方式直观易懂,true
表示存在,false
可表示"软删除"。
三、使用 map[T]struct{}
更节省内存
set := make(map[int]struct{})
// 添加元素
set[1] = struct{}{}
set[2] = struct{}{}
// 判断是否存在
if _, ok := set[1]; ok {
fmt.Println("1 在集合中")
}
// 删除元素
delete(set, 2)
// 遍历
for k := range set {
fmt.Println("元素:", k)
}
⚠️
struct{}
是占用 0 字节内存的空结构体,适合只关心 key 的场景,更节省资源。
四、封装一个简单的 Set 类型(示例)
type IntSet map[int]struct{}
// 添加元素
func (s IntSet) Add(val int) {
s[val] = struct{}{}
}
// 删除元素
func (s IntSet) Remove(val int) {
delete(s, val)
}
// 判断是否存在
func (s IntSet) Contains(val int) bool {
_, ok := s[val]
return ok
}
// 遍历集合
func (s IntSet) Elements() []int {
elems := make([]int, 0, len(s))
for k := range s {
elems = append(elems, k)
}
return elems
}
使用:
s := IntSet{}
s.Add(10)
s.Add(20)
fmt.Println("Contains 10:", s.Contains(10)) // true
fmt.Println("所有元素:", s.Elements())
五、适合的应用场景
- • 去重操作(如处理唯一用户名、ID 集合等)
- • 判断某元素是否已经出现过
- • 实现某些算法(如交集、并集、差集)
- • 限制重复请求、唯一标记等功能
六、小结
用法 | 示例 |
---|---|
定义集合 | set := map[int]struct{}{} |
添加元素 | set[val] = struct{}{} |
判断元素是否存在 | _, ok := set[val] |
删除元素 | delete(set, val) |
遍历集合 | for k := range set {} |
通过使用 map
模拟 Set,Go 语言可以轻松完成集合相关的所有操作,简洁高效,且便于扩展封装。