假设我们有以下代码:

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中,您可能会在运行时担心空引用的取消,但这不会编译-这是非常正确的.当然,在‘if’中,一旦mutableProperty不再为NULL.

My question is what's the best way to handle this?

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.

There's this:

fun function(argument: SomeOtherClass) {
    argument.mutableProperty?.let {
        doSomething(it)
        return
    }
    doOtherThing()
}

这有一个明显的缺点,即您需要提前返回或避免执行后续代码-在某些较小的上下文中可以,但有一些问题.

Then there's this possibility:

fun function(argument: SomeOtherClass) {
    argument.mutableProperty.let {
        when {
            it != null -> {
                doSomething(it)
            }
            else -> {
                doOtherThing()
            }
        }
    }
}

but whilst it has greater clarity of purpose, arguably it's more unwieldy and verbose than the Java-style way of dealing with this.

我遗漏了什么吗?有没有更好的习惯用法来实现这一点?

推荐答案

我不认为有一个真正"短"的方法来实现它,但是你可以简单地使用withlet以内的条件:

with(mutableVar) { if (this != null) doSomething(this) else doOtherThing() }
mutableVar.let { if (it != null) doSomething(it) else doOtherThing() }

事实上,"捕获"可变值是let的主要用例之一.

这相当于您的when语句.

始终存在您描述的选项,将其分配给变量:

val immutable = mutableVar

if (immutable != null) {
    doSomething(immutable)
} else {
    doOtherThing()
}

which is always a nice fallback in case e.g. things get too verbose.

可能没有一种非常简单的方法来实现这一点,因为只允许将last lambda参数放在()之外,因此指定两个参数并不真正适合所有其他标准函数的语法.

如果您不介意(或者如果您将传递方法引用),您可以编写一个:

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

请注意,我个人会not来做这件事,因为这些自定义构造读起来都不是很愉快.国际海事组织:坚持let/run,必要时回落至if-else.

Kotlin相关问答推荐

计算值的Elvis算子

如何避免使用公共类实现内部接口

&x是T&q;和&q;(x为?T)!=空(&Q;)?

Spring Boot kotlin协程不能并行运行

在 Kotlin 中定义基于多态函数的泛型函数

在 Kotlin 中将两个字节转换为 UIn16

Kotlin 函数中接收者和参数的类型相同

如何在 micronaut 上启用 swagger UI?

如果不在可组合函数中,如何获取 stringResource

从列表中的每个对象中 Select 属性

如何将超过 2 个 api 调用的结果与 Coroutines Flow 结合起来?

Kotlin默认使用哪种排序?

如何在使用 Gradle 的 AppEngine 项目中使用 Kotlin

Kotlin JVM 和 Kotlin Native 有什么区别?

在kotlin中初始化类变量的正确位置是什么

@StringRes、@DrawableRes、@LayoutRes等android注释使用kotlin参数进行判断

Kotlin - 错误:Could not find or load main class _DefaultPackage

在Kotlin中创建通用二维数组

Java的Kotlin:字段是否可以为空?

var str:String是可变的还是不可变的?