Kotlin高阶函数和Lambda表达式

高阶函数和Lambda表达式

高阶函数是接受函数作为参数或者将函数作为返回值的函数。我们可以将C语言中使用回调函数的函数称为高阶函数。

例如我们有一个数值处理函数processNum(),对于给定Int型数据,依次执行两个处理过程 proc1 和 proc2 :

fun processNum(num: Int, proc1: (Int) -> Int, proc2 (Int) -> Int): Int {
    return proce2(proc1(num))
}

如上,processNum()是高阶函数,它包含函数类型参数proc1proc2

高阶函数需要函数作为参数,这就要求调用时需要一个函数实参。如果在其他地方声明函数并在高阶函数调用处传入非常不利于代码阅读的连贯性(各种代码跳转很难阅读),并且有时函数的实现逻辑非常的简单,重新声明一个函数的大部分代码都是模板代码。这时Lambda表达式就有用了。

可以将Lambda理解为“字面值函数”。试想,如果在调用一个函数时我们已经知道了一个 Int 实参就是字面值 1 ,那么我们就可以直接使用1作为参数调用这个函数而不需要声明一个Int变量将它赋值为 1 然后再作为实参去调用函数! 使用Lambda表达式的思路与此类似:如果我们已经知道了这个函数参数的“样子”我们就可以直接用Lambda表达式表示出来作为实参,而不需要再声明一个函数并将函数作为实参!

Lambda表达式语法参考

it 语法糖

如果Lambda表达式只有一个参数那么可以省略该参数和 -> 并可以在Lambda表达式中使用 it 来代替该参数。在Lambda的唯一参数被省略时,it 用来代表该参数!

Lambda 表达式和闭包

Lambda表达式能够访问其闭包中的变量,不同于Java,Kotlin还可以修改这些变量。如果 this 在闭包中有定义,那么在Lambda表达式中也可以使用this。

Lambda表达式中的 this 需要特别注意,如果为Lambda表达式指定了 receiver 那么在Lambda表达式中 this 代表它的 receiver,否则 this 与其闭包中的 this 等价。 如果需要访问Lambda表达式闭包中的变量,而这个变量名和其receiver中的变量名冲突,此时需要 this@<closureName>.<varNmae> 语法来指明该变量是Lambda表达式闭包中的变量。如果情况复杂分不清 this 指向谁,那么总是使用 this@ 是不容易出错的做法!

Kotlin 标准库中的高阶函数

run 函数

不带 receiver 的 run 函数执行参数中的可执行对象,将返回值作为 run 的返回值:

/**
 * Calls the specified function [block] and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R = block()

带 receiver 的 run 将上下文中的 this 指向 receiver 并执行参数中的可执行对象,将返回值作为 run 的返回值:

/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R = block()
with 函数

换了个写法的带 receiver 的 run 函数:

/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
apply 函数

类似带 receiver 的 run 函数,可执行对象参数的执行上下文中 this 被设置为receiver。不同的是apply返回 receiver 本身。

/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }

apply 函数将处理过程“应用”到 receiver 上并返回 receiver 本身,这适用于修改 receiver 的场景,比如将某个函数的返回值修正一下。

let 函数

let 函数将 receiver 作为其可执行对象参数的实参传入并执行可执行对象,返回值是可执行对象的返回值:

/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

结合 it语法糖。一般来说在写传入 let 函数的Lambda表达式参数时往往使用 it 表示 let 的 receiver 。

also 函数

它和 let 函数的关系类似于 apply 和带 receiver的 run 函数的关系。also 函数将 receiver 作为其可执行参数的实参传入并执行可执行对象,但是其返回值为 receiver 本身

/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
如何选择?

:)

Kotlin 容器类相关高阶函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值