【问题标题】:Reasonable situations to use Kotlin's `let`使用 Kotlin 的 `let` 的合理情况
【发布时间】:2017-11-06 18:46:21
【问题描述】:

在 Kotlin 中,如果对象(let 接收者)不是 null,则通常使用 let 来执行代码,作为 if != null 检查的替代方法,如下所示:

val nullable: String? = "anything"
nullable?.let {
    println(it)
}

在哪些其他情况下使用let 有意义?

仅供参考,let 是 Kotlin 标准库的一部分,定义如下:

@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

【问题讨论】:

标签: android kotlin


【解决方案1】:

我已经看到 let 用于范围嵌套变量(忽略 let 的返回):

    some.nested.foo.bar.let { bar -> 
        doSomething(bar)
        doMoreStuff(bar)
    }

它可以很好,因为它取代了定义局部变量的需要,但我不确定它实际上有多大用处。

也可以使用apply,尽管可读性有点差,(this 在范围内而不是bar)。

【讨论】:

  • 所以基本上是为了缩短 var 名称?
【解决方案2】:

let 在您使用可以为空的var 变量时也很有用。 例如,我们有这个代码

fun doSomething(value: String) {

}

class A {
    var boo: String? = null
    fun b() {
        if (boo != null) {
            doSomething(boo)
        }
    }
}

在那里,if 块内出现编译时错误,因为 boo 可以在外部更改。要解决这个问题,我们应该创建一个val 变量

class A {
    var boo: String? = null
    fun b() {
        val b = boo
        if (b != null) {
            doSomething(b)
        }
    }
}

或使用let

class A {
    var boo: String? = null
    fun b() {
        boo?.let {
            doSomething(it)
        }
    }
} 

【讨论】:

  • 这对我来说没有意义;那为什么不直接做boo?.length呢? let 是多余的
  • @s1m0nw1 在这种情况下,你是对的。但是我试图展示一个不需要空变量的情况。
  • @s1m0nw1 我改变了例子
  • 所以知道我们回到了我在问题本身中已经提出的建议,对吧?这与var 无关。
  • @s1m0nw1 是的,你是对的。使用ifletval 都没有关系,但如果你使用varif 你必须声明一个val 变量
【解决方案3】:

范围功能

stdlib 函数let 使您能够将变量的范围限制在特定的代码块中。此处显示:

compile("a:b:c")
"io.vertx:vertx".let { v->
    compile("$v-lang-kotlin:$vertxVersion")
    compile("$v-lang-kotlin-coroutines:$vertxVersion")
} 
compile("x:y:z")

我们也可以定义一个val v: String = "io.vertx:vertx",这可能会使代码更具可读性,因为这就是我们在Java中所做的事情。然而,val 可以在整个方法中访问。我们只想让它可用于涉及 vertxcompile 单元,因此我们将持有io.vertx:vertx 的变量限制在let 块中。

可以在this thread 中找到有关不同范围函数替代方案的信息。

【讨论】:

    【解决方案4】:

    你可以通过命名来使用let in let in let

    someMethodCall()?.let{ nameOne ->
           // ....
           // some code here
           // ....
           val resultCall = nameOne
           someMethod2Call()?.let { -> nameTwo
              // ...
              val myVariable = nameTwo + resultCall
              // ... 
          }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 2023-03-15
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多