Kotlin的“ let”加猫王,以及意外的空返回值

时间:2018-11-21 16:57:42

标签: kotlin idiomatic

今天我很惊讶地发现,这种看似惯用的代码失败了:

class QuickTest {

    var nullableThing: Int? = 55

    var nullThing: Int? = null

    @Test
    fun `test let behaviour`() {
        nullableThing?.let {
            print("Nullable thing was non-null")
            nullThing?.apply { print("Never happens") }
        } ?: run {
            fail("This shouldn't have run")
        }
    }
}

之所以会这样,是因为nullThing?.apply{...}与隐式返回结合,将null传递给let,因此elvis运算符求值为null并运行第二个块。

这很难被发现。除了传统的if/else之外,我们还有其他合适的选择吗?

2 个答案:

答案 0 :(得分:2)

您可以使用also代替letalso将返回nullableThing,而let将返回lambda返回的内容。

请参阅本文:https://medium.com/@elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84(指向“ 3.返回此类型与其他类型”)。

答案 1 :(得分:1)

您的案例适合also主题。比较两个block动作:

fun <T> T.also(block: (T) -> Unit): T
fun <T, R> T.let(block: (T) -> R): R

nullableThing?.also {
    print("Nullable thing was non-null")
    nullThing?.apply { println("Never happens") }
} ?: run {
    fail("This shouldn't have run")
}

另一种惯用的方式是使用when语句

when (nullableThing) {
    null ->
        print("Nullable thing was non-null")
        nullThing?.apply { println("Never happens") }
    else -> fail("This shouldn't have run")
}
相关问题