go - 如何实现通用过滤器功能?
问题描述
假设我正在实现这个函数来过滤 Golang 中的切片:
func Filter(filter func(n int) bool) func(list []int) []int {
return func(list []int) []int {
r := make([]int, 0)
for _, n := range list {
if filter(n) {
r = append(r, n)
}
}
return r
}
}
像这样使用:
list := []int{1, 4, 3, 2, 7, 4, 9, 7}
r := Filter(func(n int) bool { return n > 3 })(list)
fmt.Println(r)
这工作正常,但我有以下问题:
- 我应该使用完整的 func 语法而不是 lambda 样式表达式吗?
- 如果我希望我的过滤器过滤任何类型的切片,我应该使用什么返回类型?
谢谢!
解决方案
据我所知,尚未接受更简洁的匿名函数表示法(“lambda”)的提议。
随着 Go 1.18 的发布,计划在 2022 年初向该语言添加类型参数(又名泛型)。然后,您将能够编写下面的程序(操场)。
如果你能等到那个时候,那就去做吧。无论如何,通常不鼓励使用
reflect
包并在代码中添加空interface{}
断言和类型断言。在 Go 1.18 之前,一种可行的替代方案是用于go generate
生成您需要的不同专业化(forint
、string
等)。package main import "fmt" func Filter[T any](filter func(n T) bool) func(T []T) []T { return func(list []T) []T { r := make([]T, 0, len(list)) for _, n := range list { if filter(n) { r = append(r, n) } } return r } } func main() { list := []int{1, 4, 3, 2, 7, 4, 9, 7} r := Filter(func(n int) bool { return n > 3 })(list) fmt.Println(r) list2 := []string{"foo", "bar", "baz", "qux", "quux"} r2 := Filter(func(s string) bool { return len(s) <= 3 })(list2) fmt.Println(r2) }
推荐阅读
- kubernetes - 如何设置使用 Helm 部署的 Gitlab 组件的日志级别?
- android - Firebase crashlytics build_id 为零,无法上传映射文件
- keyboard - 在 UIAlertController 中处理击键
- python - 在 TensorFlow EagerPyFunc 上捕获异常
- javascript - 为什么 jQuery 一次对不同的元素应用效果?
- html - 如何以反应形式Angular 9将特定的formControl重置为初始状态
- php - 将使用 ifsnop/mysqldump-php 生成的 mysql 数据库备份转储保存在本地文件夹而不是服务器上
- vba - 如何使用自动完成功能填写表格?
- windows - 适用于 Linux 的 Windows 子系统没有为本地管理员安装的发行版
- java - 比较2个整数并检查数字是否相同