我最近仔细研究了 Kotlin 的作用域函数,发现有时它们期望扩展函数作为参数。就以also和apply为例:
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 中是否有在高阶函数中使用扩展函数的模式或最佳实践?具体有什么好处?
从消费者的角度来看,两者似乎没有太大区别,我可以用几乎相同的方式称呼它们
这是因为您没有利用此处的接收器或参数。您正在使用现有的变量,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,否则作为参数可用。
| 归档时间: |
|
| 查看次数: |
137 次 |
| 最近记录: |