英文:
How can I implement a generic filter function?
问题
假设我正在用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表达式? - 如果我希望
Filter
函数可以过滤任意类型的切片,我应该使用什么返回类型?
谢谢!
英文:
Suppose I'm implementing this function for filtering a Slice in 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
}
}
To be used like this:
list := []int{1, 4, 3, 2, 7, 4, 9, 7}
r := Filter(func(n int) bool { return n > 3 })(list)
fmt.Println(r)
This works ok, but I have the following questions:
- Am I supposed to use the full func syntax instead of a lambda style expression?
- If I want my Filter to filter slices of ANY type, what return type should I use?
Thanks!
答案1
得分: 3
据我所知,目前还没有关于更简洁的匿名函数表示法("lambda")的提案被接受。
计划在2022年初发布Go 1.18时引入类型参数(也称为泛型)。届时,您将能够编写下面的程序(playground)。
如果您可以等到那个时候,建议您等待。无论如何,通常不鼓励使用reflect
包和在代码中大量使用空的interface{}
和类型断言。在Go 1.18之前的一个可行的替代方案是使用go generate
来生成所需的不同特化版本(例如int
、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)
}
英文:
-
As far as I know, no proposal for a more concise anonymous-function notation ("lambda") has been accepted yet.
-
The addition of type parameters (a.k.a. generics) to the language is planned for early 2022 with the release of Go 1.18. Then, you'll be able to write the program below (playground).
If you can wait until then, do. At any rate, using the
reflect
package and peppering one's code with the emptyinterface{}
and type assertions are generally discouraged. One viable alternative until Go 1.18 would be to usego generate
to generate the different specializations (forint
,string
, etc.) you need.<!-- languageL go -->
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) }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论