Kotlin ? vs ?.let {}

  • 本文关键字:vs Kotlin let kotlin
  • 更新时间 :
  • 英文 :


考虑一下我想使用的这个不错的实用程序扩展函数:

inline infix fun <T> T?.otherwise(other: () -> Unit): T? {
if (this != null) return this
other()
return null
}

当表达式求值为null时,它可能非常有用,例如:

val x: Any? = null
x?.let { doSomeStuff() } otherwise {Log.d(TAG,"Otherwise happened")}

,但我看到它不工作:

val x: Any? = null
x?.otherwise {Log.d(TAG,"Otherwise happened")}

查看这里的运行示例

嗯,当思考它的时候,我想这是有意义的,如果x是空的?使后缀不被执行,但我不明白为什么let在第一个例子是不同的?

是否有可能修复实用程序更强大和工作,而不必在链中有let?

首先,可以简化实现:

inline infix fun <T> T?.otherwise(other: () -> Unit): T? {
if (this == null) { other() }
return this
}

inline infix fun <T> T?.otherwise(other: () -> Unit): T? =
also { if (it == null) other() }

当你这样做的时候:

null?.otherwise { println("Otherwise happened") }

?.表示"非空执行",所以otherwise不执行。

你需要写的是:

null otherwise { println("Otherwise happened") }

注意,这与?:操作符非常相似(正如Vadik在评论中指出的):

null ?: println("Otherwise happened")

不同之处在于otherwise总是返回左边的值(与also相同),但?:在左边的值为空时返回右边的值。

在我看来,otherwise是令人困惑的,特别是因为它总是返回左值,尽管名称。您最好使用?:运算符。或者将其重命名为alsoIfNull

let示例执行是因为,当您不使用中缀特性时,它看起来像这样:

x?.let {}.otherwise {println("1")}

注意它不是?.otherwise;因此,它总是执行。

因此,要使用otherwise而不使用let,您可以省略?

x.otherwise { ... }

x?.let { doSomeStuff() }.otherwise {Log.d(TAG,"Otherwise happened")}
// ⬇️
val value = if (x != null) {
doSomeStuff()
} else {
null
}
value.otherwise {Log.d(TAG,"Otherwise happened")}
x?.otherwise { Log.d(TAG,"Otherwise happened") }
// ⬇️
if (x != null) {
otherwise { Log.d(TAG,"Otherwise happened") }
} else {
null
}

?.表示如果值不为空,则执行该方法并返回结果,否则返回null

最新更新