Kotlin Lambda表达式三类执行场景疑问解析
通用基础函数
所有示例均基于以下代码:
fun trickOrTreat(isTrick: Boolean, extraTreat: (Int) -> String): () -> Unit { if (isTrick) { println(extraTreat(2)) return trick } else { println(extraTreat(5)) return treat } } val trick = { println("No treats!") } val treat = { println("Have a treat!") }
示例1
代码
fun main(){ val coins: (Int) -> String = { quantity -> "$quantity quarters" } val cupcake: (Int) -> String = { "Have $it cupcake!" } val treatFunction = trickOrTreat(false, coins) val trickFunction = trickOrTreat(true, cupcake) }
输出
5 quarters Have 2 cupcake!
问题
为何在将trickOrTreat函数赋值给变量时,相关函数会执行?
解答
你并不是把trickOrTreat函数本身赋值给变量,而是直接调用了trickOrTreat函数,变量存储的是它返回的() -> Unit类型Lambda(treat或trick)。
调用trickOrTreat时,函数内部代码会完整执行:
- 执行
trickOrTreat(false, coins)时,进入else分支,调用extraTreat(5)(即传入的coinsLambda),打印5 quarters,最后返回treatLambda给treatFunction。 - 执行
trickOrTreat(true, cupcake)时,进入if分支,调用extraTreat(2)(即传入的cupcakeLambda),打印Have 2 cupcake!,最后返回trickLambda给trickFunction。
这就是赋值过程中代码执行的原因。
示例2
代码
fun main() { val coins: (Int) -> String = { quantity -> "$quantity quarters" } val cupcake: (Int) -> String = { "Have $it cupcake!" } val treatFunction = trickOrTreat(false, coins) val trickFunction = trickOrTreat(true, cupcake) repeat(4) { i -> treatFunction() println("iteration ${i+1}") } }
输出
5 quarters Have 2 cupcake! Have a treat! iteration 1 Have a treat! iteration 2 Have a treat! iteration 3 Have a treat! iteration 4
问题
为何在repeat循环中调用treatFunction()时,对应的Lambda未执行?
解答
这里的理解存在偏差:treatFunction()执行的是trickOrTreat返回的treatLambda(打印Have a treat!),这部分已经在输出中体现。你所说的“对应的Lambda”应该是指coins?
coins的执行时机是在调用trickOrTreat函数时:当你执行trickOrTreat(false, coins)时,函数内部会主动调用extraTreat(5)(即coinsLambda)并打印结果。而treatFunction是trickOrTreat返回的独立Lambda,它和coins没有关联,所以调用treatFunction()只会触发treat的逻辑,不会再执行coins。
示例3
代码
fun main() { val coins: (Int) -> String = { quantity -> "$quantity quarters" } val cupcake: (Int) -> String = { "Have $it cupcake!" } val treatFunction = trickOrTreat(false, coins) val trickFunction = trickOrTreat(true, cupcake) repeat(4) { i -> trickOrTreat(false, coins) println("iteration ${i+1}") } }
输出
5 quarters Have 2 cupcake! 5 quarters iteration 1 5 quarters iteration 2 5 quarters iteration 3 5 quarters iteration 4
问题
为何直接调用trickOrTreat函数时,Lambda会执行?
解答
这是由trickOrTreat函数的逻辑决定的:每次调用该函数时,在返回目标Lambda(treat或trick)之前,都会主动调用传入的extraTreat参数(即你传入的coins或cupcakeLambda),并打印其返回值。
所以每次执行trickOrTreat(false, coins),都会触发coins(5)执行,打印5 quarters,这就是你看到的Lambda执行现象。
内容的提问来源于stack exchange,提问作者nitcherry

