Risposte:
Puoi usare la funzione in questo let
modo:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Nota che devi chiamare la run
funzione 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 run
blocco verrà valutato se b
è null o se let
-block restituisce null
.
Per questo motivo, di solito vuoi solo if
un'espressione.
val a = if (b == null) {
// ...
} else {
// ...
}
In questo caso, il else
blocco verrà valutato solo se b
non è nullo.
a
non è ancora definito nell'ambito di let
e run
. Ma puoi accedere al valore di b
dentro let
con il parametro implicito it
. Questo serve allo stesso scopo immagino.
a
prima di quei blocchi di codice. Ed è a
possibile accedervi all'interno.
a
? Se lo è b
, ha it
lo stesso identico scopo. Si riassegna a
con il risultato del val
blocco?
it
dall'interno del let
blocco. Il risultato del blocco let
o run
verrà 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.
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 then
blocco con il simbolo a
legato al valore non imbustato. Altrimenti inserisci il else
blocco.
Si noti in particolare che a
è vincolato solo all'interno del then
blocco . In Kotlin puoi ottenerlo facilmente chiamando
<expr>?.also { a ->
// then-block
}
e puoi aggiungere un else
blocco come questo:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Ciò si traduce nella stessa semantica dell'idioma Swift.
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
}
let
invece di also
significa che il run
blocco verrà eseguito ogni volta che il let
blocco ritorna null
, che non è quello che vogliamo.
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
if let
dichiarazione.La Optional Binding
cosiddetta if-let
istruzione 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 Binding
per la if-let
dichiarazione è la seguente:
La
if-let
dichiarazione 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-let
dichiarazione 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 let
funzione 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 */
guard let
dichiarazione.guard-let
in Swift è semplice e potente. Verifica la presenza di una condizione e se risulta falsa, else
viene eseguita l' istruzione che normalmente uscirà da un metodo.
Esploriamo una
guard-let
dichiarazione 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-let
dichiarazione 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.
Ecco come eseguire il codice solo quando name
non è 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"
}
let
fa, ma la domanda riguarda la else
strategia che viene eseguita se l'oggetto su cui let
viene 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.
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.
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
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 }
}
a
non è possibile accedere all'internolet
erun
bloccare.