首页 > 解决方案 > Kotlin 中的 `?.apply`、`?.run` 和 `?.let` 之间的空值检查质量有什么区别吗?

问题描述

我知道约定是?.let用于检查可变变量的空值,因为?.let将确保我们正在检查的变量在执行过程中不会更改为空值block?.apply和 也一样?.run吗?

最后一件事,如果变量是不可变的,是否建议只使用简单的if?

标签: kotlin

解决方案


和Kotlin之间?.apply的空值检查质量有什么区别吗??.run?.let

是的,就空值检查质量而言,它们基本相同。事实上,如果你打开apply, let, with, also&的代码run。它们“几乎”相同,主要区别在于块 get 的执行方式、传递给块的参数以及返回的值。

inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}
inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}
inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}
inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}
inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

它们实际上只是语法糖,也就是说,您最好遵循一些关于何时使用什么的基本规则/约定。看看文章 I文章 II,它们解释了它们之间的区别,比我在这个答案中详细说明的要详细得多,以及何时使用什么的基本约定。

如果变量是不可变的,是否建议只使用简单的if

是的,事实上,如果您if对变量进行检查,那么编译器将自动理解该变量在块val内永远不会为空。if

val user: User? = null;
if (user != null) {
  // user not null
  val name = user.name // won't show any errors
}
var user: User? = null;
if (user != null) {
  // user might be null
  // Since the value can be changed at any point inside the if block (or from another thread).
  val name = user.name // will show an error
}

推荐阅读