是否在Kotlin中使用lister()将listOf()设置为null?

Nae*_*mul 0 null option kotlin kotlin-null-safety

让我们f()返回一个可为空的值。

我想做的是,
如果f()为null,则获取一个空列表,
否则,如果f()不为null,则获取单个项目的列表value

在Scala中,我们可以执行以下操作:

Option(f()).toList
Run Code Online (Sandbox Code Playgroud)

或更详细地

Option(f()).map(v => List(v)).getOrElse(List.empty)
Run Code Online (Sandbox Code Playgroud)

在Kotlin中,没有Option(假设没有Funktionale库),在Scala中null toList()与(None: Option)没有不同。

我们有Elvis运算符,但在listOf()函数内部将为null ,因此它将为

listOf(f() ?: /* What can I do here? */)
Run Code Online (Sandbox Code Playgroud)

我们想要的null是listOf(/*no argument */),但是Elvis运算符需要一个参数,因此listOf(f() ?: )将导致编译错误。

至少我们可以做

val v = f()
if (v == null) listOf() else listOf(v)
Run Code Online (Sandbox Code Playgroud)

但它是两个衬里。

为此有一些表达吗?

我将在类的主要构造函数默认参数中使用此表达式,因此,如果它不是一个衬里,则将其括在方括号中,因此如下所示:

class A(
    val p1: List<V> = run {
        val v = f()
        if (v == null) listOf() else listOf(v)
    },
    val p2: ... = ...,
    ...)
Run Code Online (Sandbox Code Playgroud)

这看起来很难看,不是吗?

Nat*_*ine 5

编辑

正如@Naetmul所指出的,listOfNotNull(f())在语法上比我最初在下面发布的要好,并且还采用了可变数量的参数,例如

val myList = listOfNotNull(f(), g(), h())
Run Code Online (Sandbox Code Playgroud)

将返回所有不为空的结果的列表。


我会let在这里使用。

val myList = f()?.let { listOf(it) } ?: emptyList()
Run Code Online (Sandbox Code Playgroud)

对的返回值使用?.安全调用f(),然后用于let运行代码块。如果f()为null,则不会运行此代码块,从而导致值为null。然后,我们使用?:elvis运算符退回到一个空列表。

在这里,它分为几行以更好地理解

val myValue = f()
val myList: List<Any>
if (myValue != null) {
    myList = listOf(myValue)
} else {
    myList = emptyList()
}
Run Code Online (Sandbox Code Playgroud)