ブール値の使用?if式で


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精通ちょうど骨董ことはないよ)
Maroun

1
@MarounMaroun b可能性がnullあり、Kotlinの機能の1つはNull Safetyです。これにより、null許容可能な参照を評価しようとするとコンパイルエラーが発生します。したがって、plain bを使用するとコンパイルエラーが発生します:)
nhaarman

しかしb != nil、右側をチェックする前にそれをキャッチしませんか?
Maroun、2015

あなたは確かに言うでしょうが、私のIDEはそうではありません。私はそのようなものがうまくいくことを覚えています、私が何かを見つけることができるかどうかを確認します。
nhaarman 2015

val r = b?doSomething() ?: doSomethingElse()うまくいくと思います。
Maroun、2015

回答:


183

あなたがNULL可能ブール値を比較することができtruefalseまたはnull等価演算子を使用しました:

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つの可能な値として考えるのに役立ちます:truefalseまたはnull。そうすると、if (b != true)あなたはbが真ではないことを知っているだけで、falseor について何も知らないnull
jivimberg

7
例2。if (b != true) // b is null or false例3。if (b == false) // b is false
hmac

これは正解であり、Kotlinでは理にかなっていますが、Javaの背景から、ifステートメント内でtrueまたはfalseまたはnullと明示的に比較するのは奇妙に感じるかもしれません。
Michael Peterson

31

あなたがそうでBoolean?あるtruefalseあなたができるかどうかをきれいにチェックしたい場合:

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

それであるかどうかを確認したいnull場合は、そのelse値(または)をの値として追加できますwhen

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

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

22

Kotlinはnullチェックを静的に分析します。これは問題ありません:

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
それは確かに理にかなっています。null合体演算子はおそらく私が探していたものです。ありがとう!
nhaarman 2015

@Bantharは完全に正しくありません(2番目の例はvar?)...ローカルのvar場合、コンパイラは安全なキャストを許可できます。その他の特殊なケースについては、stackoverflow.com
questions / 34498562 /…を参照して

ヌル合体エルヴィスは課題に移動することができますval booleanVal = nullableProducer?.produceVal() ?: false; if (booleanVal) {}
Serge

6

私がブールを見たものから?null可能であるオブジェクトにブール値を返すメソッドの結果です

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
最初のものは、ifブロックをで置き換えるとコンパイルされperson?.isHome() == trueます。
ヘサム

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

//結果:「そのうちの1つはnullにできません...」

a = null
b = null

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

//結果:「どちらもnullableです!」


0

それがあなたに役立つならば、それは拡張機能を加えることはかなり簡単です。

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

var x: Boolean? = null

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

0

同様containに 操作を実行したい場合は、String以下のような等価チェックを使用できます-

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

-1

安全なオペレーター「レット」でできる

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

これは単に真実ではなく、スローされた例外で返されます。
nhaarman

以前のコメントに基づいて私の回答を編集しました
finalpets
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.