60

在 Kotlin 中,如果对象不为 null,我可以运行代码,如下所示:

data?.let {
    // execute this block if not null
}

但是,如果对象为空,我该如何执行代码块呢?

4

8 回答 8

153

您可以使用elvis运算符并使用以下代码评估另一个代码块run { ... }

data?.let {
    // execute this block if not null
} ?: run {
    // execute this block if null
}

但这似乎不像简单的if-else语句那样可读。

此外,您可能会发现此问答很有用:

于 2017-08-21T14:51:16.303 回答
43

这是使用 Elvis 运算符的简洁语法。回想一下,Elvis 运算符仅在左侧计算为 null 时才执行右侧。

data ?: doSomething()
于 2018-11-16T20:26:53.690 回答
28

您可以像这样创建一个中缀函数:

infix fun Any?.ifNull(block: () -> Unit) { 
  if (this == null) block()
}

然后你可以这样做:

data ifNull {
  // Do something
}
于 2017-08-21T15:00:10.460 回答
22

只需使用普通的if

if (data == null) {
  // Do something
}
于 2017-08-21T14:48:57.620 回答
12

您可以使用以下代码

myNullable?.let {

} ?: { 
    // do something
}()

你也可以省略fun()

myNullable?.let {

} ?: fun() { 
    // do something
}()

或者你可以打电话invoke()而不是()

myNullable?.let {

} ?: fun() { 
    // do something
}.invoke()

请注意,返回值如下所示。

val res0 = myNullable?.let {
} ?: () {

}()
val res1 = myNullable?.let {
} ?: fun() {
    "result"    
}()
val res2 = myNullable?.let {
} ?: () {
    "result"    
}()


println("res0:$res0")
println("res1:$res1")
println("res2:$res2")

结果:

res0:kotlin.Unit // () {} with empty
res1:kotlin.Unit // fun() {}
res2:result      // () {} with return
于 2019-07-01T07:24:30.990 回答
2

let也可以应用于 null,无论对象是否为 null:

data.let {d->
    if (d != null){
        // execute this block if data is not null
    } else {
        // for data is null
    }
}

于 2021-05-24T17:38:03.330 回答
0

我更喜欢这个解决方案,

fun runIfNull(any: Any?, block: () -> Unit) {
        if (any == null) block()
}

您用作:

runIfNull(any) { // it will run; }

与@Dmitry Ryadnenko 的答案相比,它有一个优势,其中一个人可能会感到困惑并且可能会错误地使用它。
你有一个功能

infix fun Any?.ifNull(block: () -> Unit) { 
  if (this == null) block()
}

如果您以这种方式在空对象上使用它:

nullObject?.ifNull { // THIS WILL NOT BE CALLED }
nullObject.ifNull { // this will be called }

该块不会被执行。
请注意错误添加的问号“?”

于 2019-10-22T10:32:04.893 回答
0

以下答案是答案的更简单版本。
如果链调用成功,则函数返回有效列表,
否则
返回emptyList()

class A(var b: B? = null)
class B(var c: C? = null)
class C(var d: D? = null)
class D(var list: List<String>?)

//1. Note ? in A?.<functionName>
fun A?.isNull(): List<String> {
    if(this == null) { // 2. access object using this keyword
        return emptyList<String>()
    }
    return this.b?.c?.d?.list ?: emptyList<String>()
}

fun main() {
    //1. Empty A object
    var a: A? = A()
    println(a.isNull()) //[]
    
    //2. Null A object
    a = null
    println(a.isNull())  //[]
    
    //3. All Valid chaining parameters
    val d = D(listOf("d"))
    val c = C(d)
    var b : B? = B(c)
    a = A(b)
    println(a.isNull())  //[d]
    
    //4. Invalid chain parameter
    b = null
    a = A(b)
    println(a.isNull()) //[]
}
于 2022-01-24T14:46:21.613 回答