阅读 112

Kotlin - 高阶函数

我们有一个字符串列表:

val strList = listOf("a", "ab", "abc", "abcd", "abcde", "abcdef", "abcdefg")
复制代码

然后我们想要过滤出字符串元素的长度是奇数的列表。我们把这个问题的解决逻辑拆成两个函数来组合实现:

val f = fun(x: Int) = x % 2 == 1 // 判断输入的 Int 是否是奇数
val g = fun(s: String) = s.length // 返回输入的字符串参数的长度
复制代码

我们再使用函数 h 来封装 “字符串长度是奇数” 这个逻辑,实现代码如下:

val h = fun(g: (String) -> Int, f: (Int) -> Boolean): (String) -> Boolean {
    return { f(g(it)) }
}
复制代码

但是这个 h 函数的声明有些长了,尤其是 3 个函数声明类型声明的箭头表达式,显得不够简洁。不过不用担心,Kotlin 中有简单好用的 Kotlin 类型别名,我们使用 G、F、H 来声明 3 个函数类型:

typealias G = (String) -> Int
typealias F = (Int) -> Boolean
typealias H = (String) -> Boolean
复制代码

那么,我们的 h 函数就可以写成下面这样了:

val h = fun(g: G, f: F): H {
    return { f(g(it)) } // 需要注意的是,这里的 {} 是不能省略的
}
复制代码

在函数体的代码 return { f(g(it)) } 中,{} 代表这是一个 Lambda 表达式,返回的是一个 (String) -> Boolean 函数类型。如果没有 {},那么返回值就是一个布尔类型 Boolean 了。

通过上面的代码例子可以看到,在 Kotlin 中,我们可以简单地实现高阶函数,现在逻辑已经实现完成,运行测试一下结果:

val strList = listOf("a", "ab", "abc", "abcd", "abcde", "abcdef", "abcdefg")
println(strList.filter { it.length % 2 == 1 })
println(strList.filter(h(g, f)))
// [a, abc, abcde, abcdefg]
// [a, abc, abcde, abcdefg]
复制代码

当你看到 h(g, f) 这样的复合函数的代码时一定很开心,感到很自然,这与数学公式很贴近,简单易懂。

文章分类
后端
文章标签