kotlin - `a?.let{} ?: run{}` 在 Kotlin 中是惯用的吗?

标签 kotlin kotlin-null-safety

我在 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/

相关文章:

android - 如何在 listView Kotlin 中获取图像

android - 应用程序关闭时如何删除房间数据库?

multithreading - 在 Kotlin 中使用线程还是协程更好?

kotlin - 结合 null 安全性和 assertNotNull

java - 如何在 Android Activity 上使用 Kotlin 扩展函数正确地进行空值检查

android - 这个 kotlin jetpack compose 代码示例中的 "provides"语法是什么?

kotlin - 在 Kotlin 中处理可为空或空列表的惯用方式

kotlin - 如何分解对象并将其简洁地添加到列表中?

kotlin - 从 kotlin 中的集合中过滤掉非空值

firebase - Firebase Firestore 中是否有任何 whereIn 查询?