我在 S.O. 中看到以下评论。帖子,我很感兴趣:
why don't you use if for null checks?
a?.let{} ?: run{}
is only appropriate in rare cases, otherwise it is not idiomatic – voddan May 15 '16 at 7:29 best way to null check in kotlin?
为什么这种结构“只适用于极少数情况”?
Kotlin 的首席工程师说,
run allows you to use multiple statements on the right side of an elvis operator https://stackoverflow.com/a/51241983/6656019
虽然我承认这实际上并不认可它是惯用的。这两个帖子似乎都来自非常受尊敬的 S.O. Kotlin 贡献者。
激发原始评论的帖子提到,如果 a
是可变的,则表达式的 let
部分很重要。在这种情况下,您需要 a?.let{} ?: run{}
而不是 if{} else {}
。
我发现我喜欢“让猫王跑”的结构。大多数情况下我应该避免吗?
感谢您提供任何见解。
最佳答案
把 foo?.let { bar(it) } ?: baz()
混为一谈很危险与 if (foo != null) bar(foo) else baz()
.
假设你有一个函数:fun computeElements(): List<Int>? = emptyList()
考虑这段代码:
val maxElement = computeElements()?.let { it.max() } ?: return
println("Max element was $maxElement")
相比:
val list: List<Int>? = computeElements()
val maxElement = if (list != null) list.max() else return
println("Max element was $maxElement")
您可能认为这是两种等效形式。但是,如果您同时运行两者,您会发现前者不会将任何内容打印到标准输出!
这是因为 it.max()
返回 null
对于一个空列表(因为没有 max 元素),这会导致 Elvis 表达式的右侧被计算,因此函数 return
早了。
简而言之,?.let { ... } ?: ...
允许评估“if-else”的两个分支,这是危险的。除了这种形式不可读(if-else
被普遍理解,而 let-run
不可读)之外,还可能出现一些细微的错误。
关于kotlin - `a?.let{} ?: run{}` 在 Kotlin 中是惯用的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52539150/