Kotlin和惯用方式基于可变值来写“如果不为空,则为其他" [英] Kotlin and idiomatic way to write, 'if not null, else...' based around mutable value

查看:165
本文介绍了Kotlin和惯用方式基于可变值来写“如果不为空,则为其他"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下代码:

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?

推荐答案

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆