Penggunaan Boolean? dalam ekspresi if


130

Jika saya memiliki nullable Boolean b, saya dapat melakukan perbandingan berikut di Java:

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

Di Kotlin, saya bisa mencapai hal yang sama dengan menggunakan !!operator:

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

Namun, penggunaan dari !!terasa agak samar bagi saya, menghindari sistem keamanan nol.

Apakah ada pendekatan yang lebih elegan untuk ini?


Sunting Sepertinya saya agak terlalu rumit. Untuk variabel lokal, seperti yang ditunjukkan Banthar , itu berhasil. Namun, Boolean saya bsebenarnya adalah "properti dengan bidang dukungan" (saya belum benar-benar memahami apa yang diberlakukan ini). Inilah hasilnya:

masukkan deskripsi gambar di sini


Mengapa Anda membutuhkan !!bdan tidak sekadar b? (Saya tidak begitu akrab dengan kotlin, hanya keingintahuan)
Maroun

1
@MarounMaroun Because bmay nulldan salah satu fitur Kotlin adalah Null Safety , yang memberikan kesalahan kompilasi saat mencoba mengevaluasi referensi nullable. Jadi, menggunakan polos bmemberikan kesalahan kompilasi :)
nhaarman

Tapi tidak akan b != nilmengerti sebelum memeriksa sisi kanan?
Maroun

Anda akan mengatakan memang, tapi IDE saya mengatakan sebaliknya. Saya ingat hal seperti itu seharusnya berhasil, saya akan melihat apakah saya dapat menemukan sesuatu.
nhaarman

Saya pikir val r = b?doSomething() ?: doSomethingElse()harus bekerja.
Maroun

Jawaban:


184

Anda dapat membandingkan boolean nullable dengan true, falseatau nullmenggunakan operator persamaan:

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
catatan: tampaknya tidak bekerja dengan operator terbalik!
Richard

7
@ Richard membantu untuk berpikir b sebagai memiliki 3 nilai yang mungkin: true, falseatau null. Kemudian ketika melakukan if (b != true)Anda hanya tahu bahwa b itu tidak benar, tetapi Anda tidak tahu apa-apa tentang falseataunull
jivimberg

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

Ini adalah jawaban yang benar dan masuk akal di Kotlin, tetapi berasal dari latar belakang Java, mungkin terasa aneh untuk membandingkan secara eksplisit dengan benar atau salah atau nol dalam pernyataan-if, yang mungkin menjelaskan mengapa ini pertanyaan dan jawaban yang populer.
Michael Peterson

31

Jika Anda ingin memeriksa dengan rapi apakah Boolean?adalah trueatau falseAnda dapat melakukan:

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

Jika Anda ingin memeriksa apakah nullAnda dapat menambahkannya (atau else) sebagai nilai di when:

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

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

22

Kotlin akan menganalisis pemeriksaan null Anda secara statis. Ini bagus:

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

Meskipun ini gagal dengan kesalahan tipe:

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

Untuk lebih lanjut lihat: http://kotlinlang.org/docs/reference/null-safety.html

Anda juga dapat menggunakan "operator penggabungan nol" (yang akan berfungsi untuk variabel yang bisa berubah):

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

Analisis hanya berfungsi untuk nilai yang tidak berubah. Jika Anda perlu melakukan ini ke kolom yang bisa diubah, simpan ke variabel lokal sementara.
Piotr Praszmo

1
Itu memang masuk akal. Operator penggabungan nol mungkin adalah yang saya cari. Terima kasih!
nhaarman

@Banthar itu tidak sepenuhnya benar (contoh kedua Anda adalah var?) ... jika itu lokal varmaka kompiler masih dapat mengizinkan cast yang aman. Untuk kasus yang lebih khusus, baca stackoverflow.com/questions/34498562/…
Jayson Minard

null coalescing elvis dapat dipindahkan ke tugasval booleanVal = nullableProducer?.produceVal() ?: false; if (booleanVal) {}
Serge

6

Dari apa yang saya lihat Boolean? adalah hasil dari metode yang mengembalikan Boolean pada objek yang nullable

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

Solusi yang saya gunakan adalah menggunakan letfungsi untuk menghapus kemungkinan nilai null yang dikembalikan seperti itu

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

5
Yang pertama dikompilasi jika Anda mengganti ifblok dengan person?.isHome() == true.
Hesam

2

Di Kotlin, Anda dapat melakukan seperti ini:

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 == truesama dengan b == true.
nhaarman

1

pertama, tambahkan fungsi sebaris kustom di bawah ini:

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
}

maka Anda dapat menulis kode seperti ini:

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

//or

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

Ya, dalam kasus: b.ifTrue {...} atau b.ifFalse {...} mungkin berguna
zyc zyc

1

Untuk Kotlin yang biasa saya gunakan adalah

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

ini hanya akan bekerja jika propertinya benar dan objeknya bukan null. Untuk kebalikannya:

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

0

Mari kita gunakan if-elsepernyataan dengan 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!")
}

// Hasil: "Salah satunya tidak dapat dibatalkan ..."

a = null
b = null

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

// Hasil: "Keduanya nullable!"


0

Sangat mudah untuk menambahkan fungsi ekstensi jika itu membantu Anda.

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

var x: Boolean? = null

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

0

Jika Anda ingin melakukan operasi serupa containdi sebuah StringAnda dapat menggunakan pemeriksaan kesetaraan seperti di bawah ini -

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

-1

Anda dapat melakukannya dengan Operator yang aman "biarkan"

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

Ini tidak benar, dan akan kembali dengan pengecualian yang dilemparkan.
nhaarman

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.