如何实现通用过滤器功能?

How can I implement a generic filter function?

假设我在 Golang 中实现这个过滤 Slice 的函数:

 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)

这工作正常,但我有以下问题:

  1. 我应该使用完整的 func 语法而不是 lambda 样式表达式吗?
  2. 如果我想让我的过滤器过滤任何类型的切片,我应该使用什么 return 类型?

谢谢!

  1. 据我所知,尚未接受更简洁的匿名函数表示法(“lambda”)的提议。

  2. 增加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).

    如果你能等到那个时候,那就去做吧。无论如何,using the reflect package and peppering one's code with the empty interface{} and type assertions are generally discouraged. One viable alternative until Go 1.18 would be to use go generate 生成您需要的不同专业(intstring 等)。

    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)
    }