【问题标题】:How can I implement a generic filter function?如何实现通用过滤器功能?
【发布时间】:2021-05-27 04:37:53
【问题描述】:

假设我正在实现这个函数来过滤 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)

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

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

谢谢!

【问题讨论】:

标签: go generics higher-order-functions


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

  2. 随着 Go 1.18 的发布,计划在 2022 年初将type parameters(又名泛型)添加到该语言中。然后,您将能够编写下面的程序(playground)。

    如果你能等到那个时候,那就去做吧。无论如何,using the reflect packagepeppering one's code with the empty interface{} and type assertions 通常不鼓励使用。在 Go 1.18 之前,一种可行的替代方法是使用 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)
    }
    

【讨论】:

猜你喜欢
  • 2019-09-05
  • 2022-11-27
  • 1970-01-01
  • 2015-06-15
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
相关资源
最近更新 更多