Kotlin和惯用方式基于可变值来写“如果不为空,则为其他" [英] Kotlin and idiomatic way to write, 'if not null, else...' based around mutable value
问题描述
假设我们有以下代码:
class QuickExample {
fun function(argument: SomeOtherClass) {
if (argument.mutableProperty != null ) {
doSomething(argument.mutableProperty)
} else {
doOtherThing()
}
}
fun doSomething(argument: Object) {}
fun doOtherThing() {}
}
class SomeOtherClass {
var mutableProperty: Object? = null
}
与Java不同,在Java中,您可能会担心在运行时进行null取消引用,而这种编译不会-完全正确.当然,一旦在'if'中,mutableProperty
可能不再为null.
Unlike in Java, where you could be left alone to worry about null dereferencing at runtime, this doesn't compile - quite rightly. Of course, mutableProperty
may no longer be null once within the 'if'.
我的问题是处理此问题的最佳方法是什么?
My question is what's the best way to handle this?
一些选择是显而易见的.不使用任何新的Kotlin语言功能,最简单的方法显然是将值复制到方法范围内,该值随后将不会更改.
A few options are apparent. Without using any new Kotlin language features, the simplest way is obviously to copy the value to a method-scope one that won't subsequently change.
有这个:
fun function(argument: SomeOtherClass) {
argument.mutableProperty?.let {
doSomething(it)
return
}
doOtherThing()
}
这有一个明显的缺点,即您需要提早返回,否则应避免执行后续代码-在某些较小的上下文中可以,但是有异味.
This has the obvious disadvantage that you need to return early or otherwise avoid executing the subsequent code - OK in certain, small contexts, but has a smell to it.
那么就有这种可能性:
fun function(argument: SomeOtherClass) {
argument.mutableProperty.let {
when {
it != null -> {
doSomething(it)
}
else -> {
doOtherThing()
}
}
}
}
但是,尽管目的更清晰,但可以说它比Java风格的处理方式更笨拙和冗长.
but whilst it has greater clarity of purpose, arguably it's more unwieldy and verbose than the Java-style way of dealing with this.
我错过了什么吗,并且有实现该目标的首选惯用法吗?
Am I missing anything, and is there a preferred idiom with which to achieve this?
推荐答案
我不认为有一种真正的简短"方法来实现它,但是您可以在with
或let
内简单地使用条件:
I don't believe there is a really "short" way to achieve it, however you can simply use a conditional within with
or let
:
with(mutableVar) { if (this != null) doSomething(this) else doOtherThing() }
mutableVar.let { if (it != null) doSomething(it) else doOtherThing() }
实际上,捕获"可变值是let
的主要用例之一.
In fact, "capturing" a mutable value is one of the main use cases of let
.
这等效于您的when
语句.
总有您描述的选项,将其分配给变量:
There is always the option you described, assigning it to a variable:
val immutable = mutableVar
if (immutable != null) {
doSomething(immutable)
} else {
doOtherThing()
}
总是很好的备用,以防万一,例如事情变得太冗长了.
which is always a nice fallback in case e.g. things get too verbose.
实际上可能没有非常好的 nice 方法,因为只允许将 last lambda参数放在()
之外,因此指定两个真的不适合所有其他标准函数的语法.
There probably isn't really a very nice way to achieve this because only the last lambda argument is allowed to be put outside the ()
, so specifying two wouldn't really fit the syntax of all of the other standard functions.
如果您不介意(或者如果您要传递方法引用),可以可以写一个:
You could write one if you don't mind that (or if you'll be passing method references instead):
inline fun <T : Any, R> T?.ifNotNullOrElse(ifNotNullPath: (T) -> R, elsePath: () -> R)
= let { if(it == null) elsePath() else ifNotNullPath(it) }
...
val a: Int? = null
a.ifNotNullOrElse({ println("not null") }, { println("null") })
这篇关于Kotlin和惯用方式基于可变值来写“如果不为空,则为其他"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!