使用布尔值?在如果表达


130

如果我具有nullable Boolean b,则可以在Java中进行以下比较:

Boolean b = ...;
if (b != null && b) {
   /* Do something */
} else {
   /* Do something else */
}

在Kotlin中,我可以通过使用!!运算符来实现相同目的:

val b: Boolean? = ...
if (b != null && b!!) {
   /* Do something */
} else {
   /* Do something else */
}

但是,使用!!感觉对我来说有点粗略,绕过了无效安全系统。

有没有更优雅的方法呢?


编辑似乎我简化了一点。如Banthar所示,对于局部变量,它确实有效。但是,我的布尔b值实际上是“具有后备字段的属性”(我并没有真正加快步伐)。结果如下:

在此处输入图片说明


为什么需要!!b而不是简单b?(我对Kotlin不太熟悉,只是
好奇

1
@MarounMaroun因为b可能是nullKotlin的功能之一,所以它是Null Safety,它在尝试评估可为空的引用时会出现编译错误。因此,使用Plain b会产生编译错误:)
nhaarman

但是b != nil在检查右侧之前不会抓住这一点吗?
Maroun

您可能确实会说,但是我的IDE却相反。我确实记得类似的事情应该起作用,我会看看是否能找到一些东西。
nhaarman

我认为val r = b?doSomething() ?: doSomethingElse()应该可以。
Maroun

Answers:


183

您可以将可以为null的布尔值与进行比较truefalsenull使用等于运算符:

var b: Boolean? = null
if (b == true) {
    // b was not null and equal true
} 
if (b == false) {
   // b is false 
}
if (b != true) { 
   // b is null or false 
}

4
注意:似乎不适用于逆运算符!
理查德(Richard)

7
@Richard它有助于认为B,为一种具有3个可能值:truefalsenull。然后,在执行操作时,if (b != true)您只会知道b不是真,但是您对false或却一无所知null
jivimberg

7
eg2。if (b != true) // b is null or falseeg3。if (b == false) // b is false
hmac

这是正确的答案,并且在Kotlin中是有意义的,但是来自Java背景,如果在if语句中显式比较true或false或null可能会感到很奇怪,这可以解释为什么这是一个如此受欢迎的问答。
迈克尔·彼得森

31

如果要彻底检查a Boolean?truefalse可以执行以下操作:

when(b) {
    true -> {}
    false -> {}
}

如果要检查是否null可以,可以在(else)中将其(或)添加为值when

when(b) {
    true -> {}
    false -> {}
    null -> {}
}

when(b) {
    true -> {}
    false -> {}
    else-> {}
}

22

Kotlin将静态分析您的空检查。这可以:

val b: Boolean? = null
if (b != null && b) {
    println(b)
}

即使此操作因类型错误而失败:

val b: Boolean? = null
if (b == null && b) {
    println(b)
}

有关更多信息,请参见:http : //kotlinlang.org/docs/reference/null-safety.html

您还可以使用“空合并运算符”(适用于可变变量):

val b: Boolean? = null
if (b ?: false) {
    println(b)
}

该分析仅适用于不可变的值。如果需要对可变字段执行此操作,请将其存储到临时局部变量。
Piotr Praszmo 2015年

1
的确如此。空合并运算符可能是我想要的。谢谢!
nhaarman

@Banthar并不完全正确(您的第二个示例是var?)...如果它是本地的,var则编译器仍然可以允许安全强制转换。欲了解更多特殊情况下,读stackoverflow.com/questions/34498562/...
杰森米纳德

空合并的猫王可以移至任务val booleanVal = nullableProducer?.produceVal() ?: false; if (booleanVal) {}
Serge

6

从我所看到的布尔值?是方法的结果,该方法在可为空的对象上返回布尔值

val person: Person? = null
....
if(person?.isHome()) { //This won't compile because the result is Boolean?
  //Do something
}

我一直在使用的解决方案是使用该let函数删除可能返回的null值,如下所示

person?.let {
  if(it.isHome()) {
    //Do something
  }
}

5
如果用替换ifblock,第一个编译person?.isHome() == true
Hesam

2

在Kotlin中,您可以这样:

val b: Boolean? = true
if (b == true) { // if b is null, this should be null == true
    /* Do something */
} else {
    /* Do something else */
}

3
b != null && b == true与相同b == true
nhaarman

1

首先,在下面添加自定义内联函数:

inline fun Boolean?.ifTrue(block: Boolean.() -> Unit): Boolean? {
    if (this == true) {
        block()
    }
    return this
}

inline fun Boolean?.ifFalse(block: Boolean?.() -> Unit): Boolean? {
    if (null == this || !this) {
        block()
    }

    return this
}

那么您可以编写如下代码:

val b: Boolean? = ...
b.ifTrue {
   /* Do something in true case */
}

//or

b.ifFalse {
   /* Do something else in false case */
}

是的,在以下情况下:b.ifTrue {...}或b.ifFalse {...}可能有用
zyc zyc

1

对于Kotlin,我通常使用的是

if (object?.booleanProperty ==true)
   { 
     //do stuff 
   }

仅当属性为true且对象不为null时,此方法才有效。相反:

if (!object?booleanProperty !=true)
   { 
     //do Stuff
   }

0

让我们使用带有的if-else语句Elvis Operator

val a: Boolean?
val b: Boolean?

a = true
b = null

if (a != null ?: b) { 
    println("One of them isn't nullable...")
} else {
    println("Both are nullables!")
}

//结果:“其中一个不可为空...”

a = null
b = null

if (a != null ?: b) { 
    println("One of them isn't nullable...")
} else {
    println("Both are nullables!")
}

//结果:“两者都是可为空!”


0

如果可以,您可以轻松添加扩展功能。

fun Boolean?.orDefault(default: Boolean = false): Boolean {
    if (this == null)
        return default
    return this
}

var x: Boolean? = null

if(x.orDefault()) {
..
}

0

如果您想contain对a 执行相同的操作,则 String可以使用如下所示的相等性检查-

if (url?.contains("xxx") == true){
  return false;
}

-1

您可以使用安全的运算符“让”

val b: Boolean? = null
b?.let { flag ->
    if(flag){
        // true Block
    } else {
        // false Block
    }
}

这根本不是真的,并且会返回抛出异常。
nhaarman

根据先前的评论编辑了我的答案
决赛
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.