小狮子的Kotlin学习之路(十五)

Kotlin高阶函数

最近因为工作原因,一直没有时间写博客,距离上一篇已经过去好久了,遵从遗忘曲线,我都不记得之前写了些什么+_+,于是花了一些时间把前面的翻看了一下~~

接下来,要学习的是高阶函数了。

在Kotlin中,函数是第一位的,官方所说的“头等的”。和通常的理解不太一样的是,在Kotlin中函数不仅可以作为变量,而且可以作为参数或返回值。

而以上所说的作为变量、参数和返回值,就是高阶函数的特点。

直接搬来官方的示例:

    fun <T, R> Collection<T>.fold(initial: R, combine: (acc: R, nextElement: T) -> R): R {
        var accumulator: R = initial
        for (element: T in this) {
            accumulator = combine(accumulator, element)
        }
        return accumulator
    }

是不是看着一脸懵? 

答案是肯定的,因为前面见到的函数,都是最普通的函数,没有像这样的花里胡哨的。

接下来,我们把它拆分开来,一步一步地去看。

  1. 首先,它是个泛型Collection<T>的扩展函数(如果不知道扩展函数的,可以看看前一篇)。
  2. 它有两个参数,第一个参数是initial,类型是R;第二个参数combine,是一个Lambda表达式,最终的类型依旧是R,而具有这种(T, R) -> R的写法在Kotlin中称作函数类型
  3. 它有一个返回值R。
  4. 它的实现说明: 将initial 赋值给accumulator,通过对T的循环,将accumulator作为参数传递给combine,且将其返回结果赋值给accumulator,最终返回accumulator的值。

认识了它,就需要再通过使用它来进一步了解。

它既然是一个Collection<T>的扩展函数,那使用它的场景必须在实现Collection<T>类中。

通过这张图,可以看到Collection接口的实现还是很多的(关于这类,童鞋们可以在开发过程中去详细了解,在Kotlin的标准库中),我们选一个List来作为示例。

越简单,越容易理解。就以MutableList<Int>作为示例。

第一步,定义一个待处理的对象

val mutableList = mutableListOf(1, 2, 3, 4)

第二步,调用fold函数

定义的待处理对象是一个MutableList<Int>对象,它实现了Collection<T>接口(这里使用了自动类型推断,意思就是说,编译器如果能够推断出所定义的类型,则不用显式地声明它)。

要调用fold函数,那么就需要提供fold函数所必须的参数。

从泛型声明<T, R>可以看出,T作为待处理函数的泛型声明,R作为返回值的返回类型的泛型声明。

按照函数的调用方式(在Kotlin中调用函数有多种形式,最常用的是`.`调用)

需要说的是,泛型相当于一个声明,在实际使用中,会被替换为对应的类型,比如这里T,在示例中则指的是Int类型。

假定我们的返回值也是Int类型,那么R也就是Int类型。

函数的第一个参数initial则可以传入Int类型,而第二个是一个函数类型。

按照之前对函数的理解,可以定义一个匿名函数,作为第二个参数:

            val combine = fun (a: Int, b: Int): Int {
                return a + b
            }

然后,这个fold函数就可以这样调用了

            val combine = fun (a: Int, b: Int): Int {
                return a + b
            }
            mutableList.fold(0, combine)

理解了吧,就是说,fold函数的第二个参数需要传入一个函数。

由于combine是一个匿名函数,结合起来,可以是这样写

            mutableList.fold(0, fun (a: Int, b: Int): Int {
                return a + b
            })

那更简单的,结合函数表达式

            mutableList.fold(0, fun (a: Int, b: Int): Int = a + b)

还能不能再简单一点?

结合Lambda表达式

            mutableList.fold(0, { a: Int, b: Int ->
                a + b
            }) 

而当函数的最后一个参数是Lambda表达式时,可以将Lambda表达式放在函数参数括弧外面,即

            mutableList.fold(0) { a: Int, b: Int ->
                a + b
            }

好了,如果你不需要使用Lambda表达式中的某个变量,那还可以这么写

            mutableList.fold(0) { _, b: Int ->
                b
            }

现在,你是不是已经爱上了Kotlin编程,如果是的,我们一起继续加油吧,童鞋们。

至此,你已经可以使用Kotlin写基本的小应用了,下一篇,我们详细介绍一下本篇中的函数类型Lambda表达式。

关注微信公众号,一起学习讨论

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读