今天我很惊讶地发现,这种看似惯用的代码失败了:
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
之外,我们还有其他合适的选择吗?
答案 0 :(得分:2)
您可以使用also
代替let
。 also
将返回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")
}