funk 包
- 快速开发首选,但注意性能开销
- 生产环境热路径建议用原生循环
- Go 1.18+ 可用泛型替代
funk 简介与安装
funk 是一个提供函数式编程工具的 Go 包,类似于 JavaScript 的 Lodash。
go get github.com/thoas/go-funk
常见操作
查找与过滤
import "github.com/thoas/go-funk"
type User struct {
ID int
Name string
Age int
Active bool
}
func funkExamples() {
users := []User{
{ID: 1, Name: "Alice", Age: 25, Active: true},
{ID: 2, Name: "Bob", Age: 30, Active: false},
{ID: 3, Name: "Charlie", Age: 35, Active: true},
}
// 查找元素
user := funk.Find(users, func(u User) bool {
return u.ID == 2
}).(User)
fmt.Println("找到用户:", user.Name)
// 过滤活跃用户
activeUsers := funk.Filter(users, func(u User) bool {
return u.Active
}).([]User)
// 映射到 ID 列表
ids := funk.Map(users, func(u User) int {
return u.ID
}).([]int)
// 检查是否存在
exists := funk.Contains(ids, 2)
fmt.Println("ID 2 存在:", exists)
}
链式操作
func funkChaining() {
users := []User{
{ID: 1, Name: "Alice", Age: 25, Active: true},
{ID: 2, Name: "Bob", Age: 17, Active: true},
{ID: 3, Name: "Charlie", Age: 35, Active: false},
}
// 链式操作:过滤 + 映射
result := funk.Chain(users).
Filter(func(u User) bool { return u.Age >= 18 }).
Filter(func(u User) bool { return u.Active }).
Map(func(u User) string { return u.Name }).
Value().([]string)
fmt.Println("成年活跃用户:", result)
}
其他实用功能
func funkUtilities() {
numbers := []int{1, 2, 2, 3, 4, 4, 5}
// 去重
unique := funk.Uniq(numbers).([]int)
fmt.Println("去重后:", unique) // [1, 2, 3, 4, 5]
// 反转
reversed := funk.Reverse(numbers).([]int)
// 分块
chunks := funk.Chunk(numbers, 2).([][]int)
fmt.Println("分块:", chunks) // [[1,2], [2,3], [4,4], [5]]
// 求和
sum := funk.Sum(numbers)
fmt.Println("总和:", sum)
// 检查全部满足条件
allPositive := funk.Every(numbers, func(n int) bool {
return n > 0
})
// 检查任一满足条件
hasEven := funk.Some(numbers, func(n int) bool {
return n%2 == 0
})
}
funk vs 原生遍历
性能对比
// 基准测试
func BenchmarkFunkFind(b *testing.B) {
users := generateUsers(10000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
funk.Find(users, func(u User) bool {
return u.ID == 5000
})
}
}
func BenchmarkNativeFind(b *testing.B) {
users := generateUsers(10000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, u := range users {
if u.ID == 5000 {
break
}
}
}
}
// 典型结果:
// BenchmarkFunkFind-8 20000 85000 ns/op
// BenchmarkNativeFind-8 50000 35000 ns/op
// 原生方式快约 2.4 倍
选择建议
✅ 推荐使用 funk:
- 原型开发和快速迭代
- 复杂的数据转换链
- 一次性数据处理脚本
- 可读性优先于性能的场景
✅ 推荐使用原生遍历:
- 高性能要求的热路径
- 大数据集处理
- 需要提前退出的复杂逻辑
- 性能敏感的 API 接口
泛型替代方案(Go 1.18+)
CodeBlock Loading...