Go 并没有支持集合类型,我们需要自己实现:
https://go.dev/play/p/uVDCiN4Cbpt
package main
import "fmt"
type Set map[string]bool
func (s Set) Add(item string) {
s[item] = true
}
func (s Set) Remove(item string) {
delete(s, item)
}
func (s Set) Contains(item string) bool {
_, exists := s[item]
return exists
}
func main() {
mySet := make(Set)
mySet.Add("apple")
mySet.Add("banana")
mySet.Add("orange")
for item := range mySet {
fmt.Println(item)
}
fmt.Println(mySet.Contains("apple")) // 输出: true
fmt.Println(mySet.Contains("grape")) // 输出: false
mySet.Remove("banana")
fmt.Println(mySet.Contains("banana")) // 输出: false
}
注意:
- 使用 map 做底层存储,因此实现的 set 也是无序的
- map 不是线程安全的,如果有并发操作,需要加锁
- 如果真的要使用集合类型,应该再扩充一下交集,差集等方法
改进
参考 https://github.com/deckarep/golang-set
的设计:
https://go.dev/play/p/BKWT84lXfuz
package main
import "fmt"
type Set[T comparable] map[T]struct{}
func (s Set[T]) Add(item T) {
s[item] = struct{}{}
}
func (s Set[T]) Remove(item T) {
delete(s, item)
}
func (s Set[T]) Contains(item T) bool {
_, exists := s[item]
return exists
}
func main() {
mySet := make(Set[string])
mySet.Add("apple")
mySet.Add("banana")
mySet.Add("orange")
for item := range mySet {
fmt.Println(item)
}
fmt.Println(mySet.Contains("apple")) // 输出: true
fmt.Println(mySet.Contains("grape")) // 输出: false
mySet.Remove("banana")
fmt.Println(mySet.Contains("banana")) // 输出: false
}
优化点:
- 空结构体不占空间
- 泛型让代码复用性更好