使用扩展函数作为函数参数有什么好处?

And*_*eas 5 kotlin

我最近仔细研究了 Kotlin 的作用域函数,发现有时它们期望扩展函数作为参数。就以alsoapply为例:

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

public inline fun <T> T.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}
Run Code Online (Sandbox Code Playgroud)

从消费者的角度来看,两者似乎没有太大区别,我可以用几乎相同的方式来称呼它们:

fun main() {
    val logger = Logger.getLogger("Test")
    logger.info("A").apply {
        logger.info("B")
    }.also {
        logger.info("C")
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我想知道我在这里错过了什么?Kotlin 中是否有在高阶函数中使用扩展函数的模式或最佳实践?具体有什么好处?

Jof*_*rey 5

从消费者的角度来看,两者似乎没有太大区别,我可以用几乎相同的方式称呼它们

这是因为您没有利用此处的接收器或参数。您正在使用现有的变量,logger而不是接收器apply提供的任何变量。

作用域函数的要点之一是当您还没有变量时在表达式上使用它们:

Logger.getLogger("Test").apply {
    info("A") // the logger is provided as `this` here
}

Logger.getLogger("Test2").also { logger ->
    logger.info("A") // the logger is provided as parameter here
}

Logger.getLogger("Test2").also {
    it.info("A") // using the implicit `it` parameter
}
Run Code Online (Sandbox Code Playgroud)

正如您在上面的示例中可能注意到的那样,采用带有接收器的 lambda 的高阶函数将为函数的调用者提供不同的值。在块内,参数将在接收器的情况下可用this,否则作为参数可用。