Uso di Boolean? in se espressione


130

Se ho un nullable Boolean b, posso fare il seguente confronto in Java:

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

In Kotlin, posso ottenere lo stesso utilizzando l' !!operatore:

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

Tuttavia, l'uso di mi !!sembra un po 'impreciso, aggirando il sistema di sicurezza nulla.

C'è un approccio più elegante per questo?


Modifica Sembra che ho semplificato un po '. Per le variabili locali, come mostra Banthar , funziona. Tuttavia, il mio booleano bè in realtà una "proprietà con un campo di supporto" (non sono ancora al passo con ciò che questo impone). Questo è il risultato:

inserisci qui la descrizione dell'immagine


Perché hai bisogno !!be non semplicemente b? (Non ho molta familiarità con kotlin, solo curiosità)
Maroun

1
@MarounMaroun Poiché bpotrebbe essere nulle una delle funzionalità di Kotlin è Null Safety , che fornisce errori di compilazione quando si tenta di valutare riferimenti nullable. Pertanto, l'utilizzo di plain bdà un errore di compilazione :)
nhaarman

Ma non lo b != nilprendi prima di controllare il lato destro?
Maroun

Diresti davvero, ma il mio IDE dice il contrario. Ricordo che qualcosa del genere dovrebbe funzionare, vedrò se riesco a trovare qualcosa.
nhaarman

Penso che val r = b?doSomething() ?: doSomethingElse()dovrebbe funzionare.
Maroun

Risposte:


184

È possibile confrontare booleana annullabile con true, falseo nullcon operatore di uguaglianza:

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
nota: non sembra funzionare con l'operatore inverso!
Richard

7
@Pluto aiuta a pensare B come avere 3 valori possibili: true, falseo null. Quindi quando lo fai if (b != true)sai solo che b non è vero, ma non sai nulla di falseonull
jivimberg

7
EG2. if (b != true) // b is null or falseEG3. if (b == false) // b is false
hmac

Questa è la risposta corretta e ha senso in Kotlin, ma provenendo da un background Java può sembrare strano confrontarlo esplicitamente con vero o falso o nullo all'interno di un'istruzione if, il che potrebbe spiegare perché questa è una domanda e risposta così popolare.
Michael Peterson,

31

Se vuoi controllare in modo pulito se Boolean?è trueo falsepuoi fare:

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

Se vuoi controllare se è nullpossibile aggiungerlo (o else) come valore in when:

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

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

22

Kotlin analizzerà staticamente i tuoi assegni nulli. Questo va bene:

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

Anche se questo non riesce con errore di tipo:

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

Per ulteriori informazioni, vedere: http://kotlinlang.org/docs/reference/null-safety.html

Puoi anche usare "null coalescing operator" (che funzionerà per variabili mutabili):

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

L'analisi funziona solo per valori immutabili. Se è necessario eseguire questa operazione su un campo modificabile, memorizzarlo in una variabile locale temporanea.
Piotr Praszmo

1
Ha senso, davvero. L'operatore di coalescenza nullo è probabilmente quello che stavo cercando. Grazie!
nhaarman

@Banthar che non è completamente corretto (il tuo secondo esempio sarebbe var?) ... se è locale, varil compilatore può comunque consentire il cast sicuro. Per casi più speciali, leggi stackoverflow.com/questions/34498562/…
Jayson Minard

null elvis coalescente può essere spostato in incaricoval booleanVal = nullableProducer?.produceVal() ?: false; if (booleanVal) {}
Serge

6

Da quello che ho visto il booleano? è il risultato di un metodo che restituisce Boolean su un oggetto che è nullable

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

La soluzione che ho utilizzato è utilizzare la letfunzione per rimuovere il possibile valore nullo restituito in questo modo

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

5
Il primo viene compilato se sostituisci ifblock con person?.isHome() == true.
Hesam

2

In Kotlin, puoi fare così:

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è lo stesso di b == true.
nhaarman

1

per prima cosa, aggiungi la funzione inline personalizzata di seguito:

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
}

quindi puoi scrivere codice come questo:

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

//or

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

Sì, nel caso: b.ifTrue {...} o b.ifFalse {...} potrebbe essere utile
zyc zyc

1

Per Kotlin quello che uso normalmente è

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

questo funzionerebbe solo quando la proprietà è vera e l'oggetto non è nullo. Per il contrario:

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

0

Usiamo if-elseun'istruzione con 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!")
}

// Risultato: "Uno di loro non è annullabile ..."

a = null
b = null

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

// Risultato: "Entrambi sono annullabili!"


0

È abbastanza facile aggiungere una funzione di estensione se questo ti aiuta.

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

var x: Boolean? = null

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

0

Nel caso in cui si desideri eseguire operazioni allo stesso modo containsu un, Stringè possibile utilizzare il controllo di uguaglianza come di seguito:

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

-1

Puoi farlo con Operatore sicuro "lascia"

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

Questo semplicemente non è vero e tornerà in un'eccezione generata.
nhaarman

Ho modificato la mia risposta in base al commento precedente
finalpets
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.