Swift if let statement in Kotlin


123

In Kotlin c'è un equivalente al codice Swift qui sotto?

if let a = b.val {

}
else {

}

Risposte:


255

Puoi usare la funzione in questo letmodo:

val a = b?.let {
    // If b is not null.
} ?: run {
    // If b is null.
}

Nota che devi chiamare la runfunzione solo se hai bisogno di un blocco di codice. Puoi rimuovere il run-block se hai solo un oneliner dopo l'operatore elvis ( ?:).

Tieni presente che il runblocco verrà valutato se bè null o se let-block restituisce null.

Per questo motivo, di solito vuoi solo ifun'espressione.

val a = if (b == null) {
    // ...
} else {
    // ...
}

In questo caso, il elseblocco verrà valutato solo se bnon è nullo.


41
Non è equivalente. anon è possibile accedere all'interno lete runbloccare.
Jacky Choi

6
anon è ancora definito nell'ambito di lete run. Ma puoi accedere al valore di bdentro letcon il parametro implicito it. Questo serve allo stesso scopo immagino.
marstran

1
Il codice swift completa l'assegnazione di aprima di quei blocchi di codice. Ed è apossibile accedervi all'interno.
Jacky Choi

1
A cosa assegna a? Se lo è b, ha itlo stesso identico scopo. Si riassegna acon il risultato del valblocco?
marstran

3
Puoi accedere solo itdall'interno del letblocco. Il risultato del blocco leto runverrà assegnato a a. Il risultato è l'ultima espressione nel blocco. Usi il compito dopo let / runè finito, proprio come fai con qualsiasi altro compito normale.
marstran

51

Per prima cosa assicuriamoci di comprendere la semantica dell'idioma Swift fornito:

if let a = <expr> {
     // then-block
}
else {
     // else-block
}

Significa questo: "se il <expr>risultato è un opzionale non nullo, inserisci il thenblocco con il simbolo alegato al valore non imbustato. Altrimenti inserisci il elseblocco.

Si noti in particolare che aè vincolato solo all'interno del thenblocco . In Kotlin puoi ottenerlo facilmente chiamando

<expr>?.also { a ->
    // then-block
}

e puoi aggiungere un elseblocco come questo:

<expr>?.also { a ->
    // then-block
} ?: run {
    // else-block
}

Ciò si traduce nella stessa semantica dell'idioma Swift.


11

La mia risposta è totalmente una copia del gatto dagli altri. Tuttavia, non riesco a capire facilmente la loro espressione. Quindi immagino che sarebbe bello fornire una risposta più comprensibile.

In rapida:

if let a = b.val {
  //use "a" as unwrapped
}
else {

}

A Kotlin:

b.val?.let{a -> 
  //use "a" as unwrapped
} ?: run{
  //else case
}

Usare letinvece di alsosignifica che il runblocco verrà eseguito ogni volta che il letblocco ritorna null, che non è quello che vogliamo.
Marko Topolnik

6

A differenza di Swift, non è necessario scartare l'opzionale prima di usarlo in Kotlin. Potremmo semplicemente controllare se il valore non è nullo e il compilatore tiene traccia delle informazioni sul controllo che hai eseguito e consente di usarlo come non imbustato.

In Swift:

if let a = b.val {
  //use "a" as unwrapped
} else {

}

A Kotlin:

if b.val != null {
  //use "b.val" as unwrapped
} else {

}

Fare riferimento alla documentazione: (null-safety) per altri casi d'uso simili


Funziona solo se b è una variabile locale. E le variabili di classe?
Warpzit

5

if let dichiarazione.

La Optional Bindingcosiddetta if-letistruzione di Swift viene utilizzata per scoprire se un facoltativo contiene un valore e, in tal caso, per rendere tale valore disponibile come costante o variabile temporanea. Così, una Optional Bindingper la if-letdichiarazione è la seguente:

La if-letdichiarazione di Swift :

let b: Int? = 50

if let a = b {
    print("Good news!")
} else {
    print("Equal to 'nil' or not set")
}

/*  RESULT: Good news!  */

In Kotlin, come in Swift, per evitare arresti anomali causati dal tentativo di accedere a un valore nullo quando non è previsto, b.let { }viene fornita una sintassi specifica (come nel secondo esempio) per scartare correttamente nullable types:

Equivalente di Kotlin 1 della if-letdichiarazione di Swift :

val b: Int? = null
val a = b

if (a != null) { 
    println("Good news!")
} else { 
    println("Equal to 'null' or not set")
}

/*  RESULT: Equal to 'null' or not set  */

La letfunzione di Kotlin , se utilizzata in combinazione con l'operatore di chiamata sicura ?:, fornisce un modo conciso per gestire le espressioni nullable.

Equivalente 2 di Kotlin (funzione Inline let e operatore di Elvis) dell'istruzione di Swift if-let:

val b: Int? = null

val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)

/*  RESULT: Equal to 'null' or not set  */

inserisci qui la descrizione dell'immagine

guard let dichiarazione.

guard-letin Swift è semplice e potente. Verifica la presenza di una condizione e se risulta falsa, elseviene eseguita l' istruzione che normalmente uscirà da un metodo.

Esploriamo una guard-letdichiarazione di Swift :

let b: Int? = nil

func testIt() {
    guard let a = b else {
        print("Equal to 'nil' or not set")
        return
    }
    print("Good news!")
}
testIt()

/*  RESULT: Equal to 'nil' or not set  */

L'effetto simile di Kotlin della guard-letdichiarazione di Swift :

A differenza di Swift, in Kotlin, non c'è alcuna dichiarazione di guardia . Tuttavia, puoi usare Elvis Operator- ?:per ottenere un effetto simile.

val b: Int? = 50

fun testIt() {
    val a = b ?: return println("Equal to 'null' or not set")
    return println("Good news!")
}
testIt()

/*  RESULT: Good news!  */

Spero che questo ti aiuti.


4

Ecco come eseguire il codice solo quando namenon è nullo:

var name: String? = null
name?.let { nameUnwrapp ->
    println(nameUnwrapp)  // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
    println(nameUnwrapp)  // printed "Alex"
}

se nome == codice nullo in {} non eseguire, se nome come stringa - codice eseguire: nomeUnwrapp == nome.
Александр Яковенко

1
Non penso che questo sia ciò che sta chiedendo OP, sono sicuro che OP sa già cosa letfa, ma la domanda riguarda la elsestrategia che viene eseguita se l'oggetto su cui letviene chiamato è null. Swift lo ha in modo più naturale (discutibile). Ma avendo fatto molto sia Kotlin che Swift, vorrei che Kotlin avesse un semplice scartare come fa Swift.
kalehv

2

Ecco la mia variante, limitata al caso molto comune "se non nullo".

Prima di tutto, definiscilo da qualche parte:

inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
    if (obj != null) {
        block(obj)
    }
}

Probabilmente dovrebbe esserlo internal , per evitare conflitti.

Ora converti questo codice Swift:

if let item = obj.item {
    doSomething(item)
}

A questo codice Kotlin:

ifNotNull(obj.item) { item -> 
    doSomething(item)
}

Nota che come sempre con i blocchi in Kotlin, puoi eliminare l'argomento e utilizzare it:

ifNotNull(obj.item) {
    doSomething(it)
}

Ma se il blocco è più di 1-2 righe, probabilmente è meglio essere espliciti.

Questo è il più simile a Swift come ho potuto trovare.


0

C'è un modo simile in kotlin per ottenere lo stile if-let di Swift

if (val a = b) {
    a.doFirst()
    a.doSecond()
}

È inoltre possibile assegnare più valori nullable

if (val name = nullableName, val age = nullableAge) {
    doSomething(name, age)
}

Questo tipo di approccio sarà più adatto se i valori nullable vengono usati per più di 1 volta. A mio parere, aiuta dal punto di vista delle prestazioni perché il valore nullable verrà verificato solo una volta.

fonte: Discussione Kotlin


1
Tieni presente che l'approccio che stai mostrando non si compila attualmente. È solo un suggerimento su come modificare la lingua Kotlin per affrontare questo problema. Quindi, questa non è una soluzione valida.
Peter F

0

Aggiungo questa risposta per chiarire la risposta accettata perché è troppo grande per un commento.

Lo schema generale qui è che puoi usare qualsiasi combinazione delle funzioni di ambito disponibili in Kotlin separate dall'operatore Elvis in questo modo:

<nullable>?.<scope function> {
    // code if not null
} :? <scope function> {
    // code if null
}

Per esempio:

val gradedStudent = student?.apply {
    grade = newGrade
} :? with(newGrade) {
    Student().apply { grade = newGrade }
}

-1

L'opzione più pulita secondo me è questa

Swift:

if let a = b.val {

} else {

}

Kotlin

b.val.also { a ->

} ?: run {

}

-1

Swift if let statement in Kotlin

La risposta breve è usare il semplice IF-ELSE poiché al momento di questo commento non esiste alcun equivalente in Kotlin LET,

    if(A.isNull()){
// A is null
    }else{
// A is not null
    }
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.