golang通用泛型切片、映射、集合和迭代器工具插件库go-generics的使用
Go-generics - Go语言的通用泛型切片、映射、集合和迭代器工具
简介
go-generics是一个类型安全的通用工具库,为Go语言提供了切片、集合和goroutine模式的实用功能。
兼容性说明
这是该库的第4版,适用于Go 1.23版本。
切片(slices)包
slices
包在三个方面很有用:
- 封装了难以记忆的Go惯用法,用于在切片中间插入和删除元素
- 添加了使用负整数从切片右端索引的能力
- 包含
Map
、Filter
等函数,用于通过回调处理切片元素
示例代码
package main
import (
"fmt"
"github.com/bobg/go-generics/v4/slices"
)
func main() {
// 创建切片
s := []int{1, 2, 3, 4, 5}
// 使用负索引获取最后一个元素
last := slices.Get(s, -1)
fmt.Println("Last element:", last) // 输出: 5
// 在索引2处插入元素
s = slices.Insert(s, 2, 6, 7)
fmt.Println("After insert:", s) // 输出: [1 2 6 7 3 4 5]
// 删除索引-2的元素(倒数第二个)
s = slices.Delete(s, -2)
fmt.Println("After delete:", s) // 输出: [1 2 6 7 3 5]
// 使用Map函数处理切片
doubled := slices.Map(s, func(x int) int { return x * 2 })
fmt.Println("Doubled:", doubled) // 输出: [2 4 12 14 6 10]
// 使用Filter函数过滤切片
evens := slices.Filter(s, func(x int) bool { return x%2 == 0 })
fmt.Println("Even numbers:", evens) // 输出: [2 6]
}
集合(set)包
set
包实现了常见的集合操作函数:Intersect
、Union
、Diff
等,以及用于添加和删除项、检查项是否存在和迭代项的成员函数。
示例代码
package main
import (
"fmt"
"github.com/bobg/go-generics/v4/set"
)
func main() {
// 创建集合
s1 := set.New[int]()
s1.Add(1, 2, 3)
s2 := set.New[int]()
s2.Add(2, 3, 4)
// 并集
union := set.Union(s1, s2)
fmt.Println("Union:", union) // 输出: {1, 2, 3, 4}
// 交集
intersect := set.Intersect(s1, s2)
fmt.Println("Intersection:", intersect) // 输出: {2, 3}
// 差集
diff := set.Diff(s1, s2)
fmt.Println("Difference (s1 - s2):", diff) // 输出: {1}
// 检查元素是否存在
fmt.Println("Contains 2:", s1.Contains(2)) // 输出: true
fmt.Println("Contains 5:", s1.Contains(5)) // 输出: false
// 删除元素
s1.Remove(2)
fmt.Println("After remove:", s1) // 输出: {1, 3}
}
并行(parallel)包
parallel
包包含用于协调并行工作者的函数:
示例代码
package main
import (
"fmt"
"github.com/bobg/go-generics/v4/parallel"
"sync"
)
func main() {
// Consumers示例
var wg sync.WaitGroup
wg.Add(1)
// 创建3个消费者
consume := parallel.Consumers[int](3, func(i int) {
defer wg.Done()
fmt.Printf("Worker %d received: %d\n", i, i*10)
})
// 发送数据给消费者
for i := 1; i <= 3; i++ {
consume(i)
}
wg.Wait()
// Values示例
results := parallel.Values(3, func(i int) string {
return fmt.Sprintf("result-%d", i+1)
})
fmt.Println("Results:", results) // 输出: [result-1 result-2 result-3]
// Protect示例
protected := parallel.Protect(42)
protected.With(func(val *int) {
*val += 10
fmt.Println("Protected value:", *val) // 输出: 52
})
}
总结
go-generics库为Go语言提供了强大的泛型工具,包括:
- 增强的切片操作
- 集合操作
- 并行处理模式
这些工具可以帮助开发者编写更简洁、更安全的代码,特别是在处理集合和并发场景时。
更多关于golang通用泛型切片、映射、集合和迭代器工具插件库go-generics的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang通用泛型切片、映射、集合和迭代器工具插件库go-generics的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
go-generics 库使用指南
go-generics 是一个为 Go 1.18+ 泛型设计的通用工具库,提供了泛型切片、映射、集合和迭代器等实用功能。下面我将详细介绍其主要功能和使用方法。
安装
go get github.com/JustinTimperio/go-generics
核心功能
1. 切片操作 (Slices)
import "github.com/JustinTimperio/go-generics/slices"
func main() {
// 创建切片
s := slices.New[int](1, 2, 3, 4, 5)
// 过滤
even := slices.Filter(s, func(x int) bool { return x%2 == 0 })
// 映射转换
doubled := slices.Map(s, func(x int) int { return x * 2 })
// 归约
sum := slices.Reduce(s, 0, func(acc, x int) int { return acc + x })
// 包含检查
contains := slices.Contains(s, 3)
// 去重
unique := slices.Unique([]int{1, 2, 2, 3, 3, 3})
}
2. 映射操作 (Maps)
import "github.com/JustinTimperio/go-generics/maps"
func main() {
m := map[string]int{"a": 1, "b": 2, "c": 3}
// 获取所有键
keys := maps.Keys(m)
// 获取所有值
values := maps.Values(m)
// 映射转换
doubled := maps.MapValues(m, func(x int) int { return x * 2 })
// 过滤
filtered := maps.Filter(m, func(k string, v int) bool { return v > 1 })
}
3. 集合操作 (Sets)
import "github.com/JustinTimperio/go-generics/set"
func main() {
// 创建集合
s := set.New[int]()
s.Add(1, 2, 3)
// 检查元素
exists := s.Contains(2)
// 删除元素
s.Remove(2)
// 集合运算
s2 := set.New[int](3, 4, 5)
union := s.Union(s2) // 并集
intersect := s.Intersect(s2) // 交集
diff := s.Difference(s2) // 差集
}
4. 迭代器 (Iterators)
import "github.com/JustinTimperio/go-generics/iter"
func main() {
// 从切片创建迭代器
it := iter.FromSlice([]int{1, 2, 3, 4, 5})
// 过滤偶数
it = iter.Filter(it, func(x int) bool { return x%2 == 0 })
// 映射转换
it = iter.Map(it, func(x int) int { return x * 2 })
// 收集结果
result := iter.Collect(it)
// 直接迭代
it = iter.FromSlice([]string{"a", "b", "c"})
for item, ok := it.Next(); ok; item, ok = it.Next() {
fmt.Println(item)
}
}
5. 其他实用工具
import "github.com/JustinTimperio/go-generics"
func main() {
// 指针操作
x := 10
ptr := generics.Ptr(x)
deref := generics.Deref(ptr)
// 元组
pair := generics.NewPair("key", 123)
key := pair.First
value := pair.Second
// 可选值
maybe := generics.Some(42)
if val, ok := maybe.Get(); ok {
fmt.Println("Got value:", val)
}
maybe = generics.None[int]()
}
性能考虑
go-generics 在设计时考虑了性能因素:
- 尽量减少内存分配
- 使用内联优化
- 避免不必要的接口转换
但对于性能关键路径,建议进行基准测试比较。
最佳实践
- 对于简单操作,直接使用原生切片/映射可能更高效
- 对于复杂的数据处理链,使用迭代器模式可以提高可读性
- 集合操作适合需要频繁成员检查的场景
- 使用
go:generate
为特定类型生成优化代码(如果需要)
总结
go-generics 提供了丰富的泛型工具,可以大大简化 Go 中的通用数据操作。它特别适合:
- 数据处理流水线
- 复杂集合操作
- 需要类型安全的数据结构
- 函数式编程风格的代码
通过合理使用这些工具,可以编写出更简洁、更易维护的 Go 代码。