首页 文章

在Kotlin中是'a?.let {}?:run {}`惯用语?

提问于
浏览
5

我在S.O.看到了以下评论 . 发帖,我很好奇:

为什么不使用if进行空检查? a?.let {}?:run {}仅在极少数情况下适用,否则它不是惯用的 - voddan 2016年5月15日在7:29最好的方法来检查kotlin?

为什么构造"only appropriate in rare cases"?
Kotlin的首席工程师说,

run允许您在elvis运算符的右侧使用多个语句https://stackoverflow.com/a/51241983/6656019

虽然我承认实际上并不认可它是惯用的 . 这两个帖子似乎都来自备受推崇的S.O. Kotlin贡献者 .
启发原始评论的帖子提到,如果 a 是可变的,表达式的 let 部分很重要 . 在这种情况下,您需要 a?.let{} ?: run{} 而不是 if{} else {} .

我发现我喜欢"let Elvis run"构造 . 在大多数情况下我应该避免吗?
感谢您的任何见解 .

2 回答

  • 4

    在这种情况下,你需要一个?.let {}?:run {}而不是if {} else {}

    不,您可以省略 run { statement } 的运行部分并使用 a?.let{} ?: statement .

    在大多数情况下,我应该避免它吗?

    您应该在需要时使用它 . 例如 . 当您想在该场景中运行多个语句时 . 有人指出,这是一种罕见的情况 . 通常,您只会在elvis运营商的右侧看到一条声明 .
    当然不需要它.2868289不需要它 . 保持代码简单 .

  • 1

    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")
    

    您可能认为这是两种等效形式 . 但是,如果你同时运行它们,你会发现前者不会向stdout打印任何东西!

    这是因为 it.max() 为空列表返回 null (因为没有max元素),这会导致Elvis表达式的右侧被计算,因此函数 return s会提前 .

    简而言之,要评估 ?.let { ... } ?: ... allows both branches of the "if-else" ,这很危险 . 除了这种形式不可读( if-else 是普遍理解的,而 let-run 不是),可能会发生细微的错误 .

相关问题