Réponses:
Vous pouvez utiliser la let
fonction comme ceci:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Notez que vous devez appeler la run
fonction uniquement si vous avez besoin d'un bloc de code. Vous pouvez supprimer le run
-bloc si vous n'avez qu'un oneliner après l'opérateur elvis ( ?:
).
Sachez que le run
bloc sera évalué s'il b
est nul ou si le let
-bloc est évalué à null
.
Pour cette raison, vous ne voulez généralement qu'une if
expression.
val a = if (b == null) {
// ...
} else {
// ...
}
Dans ce cas, le else
-bloc ne sera évalué que s'il b
n'est pas nul.
a
n'est pas encore défini dans le cadre de let
et run
. Mais vous pouvez accéder à la valeur de b
inside the let
avec le paramètre implicite it
. Cela sert le même objectif, je suppose.
a
avant ces blocs de code. Et a
peut être consulté à l'intérieur.
a
? Si c'est le cas b
, il it
sert exactement le même objectif. Est-il réaffecté a
avec le résultat du val
-bloc?
it
partir du let
bloc. Le résultat du bloc let
ou run
sera attribué à a
. Le résultat est la dernière expression du bloc. Vous utilisez l'affectation après let
/ run
a terminé, comme vous le faites pour toute autre affectation normale.
Commençons par nous assurer que nous comprenons la sémantique de l'idiome Swift fourni:
if let a = <expr> {
// then-block
}
else {
// else-block
}
Cela signifie ceci: "si le <expr>
résultat est un optionnel non nul, entrez le then
bloc avec le symbole a
lié à la valeur non emballée . Sinon, entrez le else
bloc.
Notez en particulier qu'il a
n'est lié que dans le then
bloc- . À Kotlin, vous pouvez facilement l'obtenir en appelant
<expr>?.also { a ->
// then-block
}
et vous pouvez ajouter un else
-bloc comme ceci:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Il en résulte la même sémantique que l'idiome Swift.
Ma réponse est totalement une copie du chat des autres. Cependant, je ne comprends pas facilement leur expression. Je suppose donc que ce serait bien de fournir une réponse plus compréhensible.
En rapide:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
À Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
let
au lieu de also
signifie que le run
bloc s'exécutera à chaque let
retour du bloc null
, ce qui n'est pas ce que nous voulons.
Contrairement à Swift, il n'est pas nécessaire de déballer l'option avant de l'utiliser dans Kotlin. Nous pourrions simplement vérifier si la valeur n'est pas nulle et le compilateur suit les informations sur la vérification que vous avez effectuée et permet de les utiliser telles quelles.
Dans Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
À Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Consultez la documentation: (null-safety) pour plus de cas d'utilisation de ce type
if let
déclaration.Swift Optional Binding
(la soi-disant if-let
instruction) est utilisée pour savoir si un optionnel contient une valeur, et si c'est le cas, pour rendre cette valeur disponible comme constante ou variable temporaire. Donc, un Optional Binding
pour l' if-let
instruction est comme suit:
Déclaration de Swift
if-let
:
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
Dans Kotlin, comme dans Swift, pour éviter les plantages provoqués en essayant d'accéder à une valeur nulle alors que ce n'est pas prévu, une syntaxe spécifique (comme b.let { }
dans le deuxième exemple) est fournie pour un déroulement correct nullable types
:
Kotlin équivalent 1 de la
if-let
déclaration de 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
fonction de Kotlin , lorsqu'elle est utilisée en combinaison avec l'opérateur d'appel sécurisé ?:
, fournit un moyen concis de gérer les expressions Nullable.
Kotlin équivalent 2 (fonction let en ligne et opérateur Elvis) de l'
if-let
instruction de Swift :
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
déclaration.guard-let
La déclaration dans Swift est simple et puissante. Il vérifie certaines conditions et s'il est évalué comme faux, alors l' else
instruction s'exécute, ce qui normalement quittera une méthode.
Explorons la
guard-let
déclaration d' un 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 */
Effet similaire de Kotlin de la
guard-let
déclaration de Swift :
Contrairement à Swift, à Kotlin, il n'y a aucune déclaration de garde . Cependant, vous pouvez utiliser le Elvis Operator
- ?:
pour obtenir un effet similaire.
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! */
J'espère que cela t'aides.
Voici comment exécuter du code uniquement lorsque name
n'est pas nul:
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
fait, mais la question concerne la else
stratégie qui s'exécute si l'objet sur lequel let
est appelé est null
. Swift l'a d'une manière plus naturelle (discutable). Mais après avoir beaucoup fait à la fois Kotlin et Swift, j'aurais aimé que Kotlin ait un simple déballage comme le fait Swift.
Voici ma variante, limitée au cas très courant "sinon nul".
Tout d'abord, définissez ceci quelque part:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
Cela devrait probablement l'être internal
, pour éviter les conflits.
Maintenant, convertissez ce code Swift:
if let item = obj.item {
doSomething(item)
}
À ce code Kotlin:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Notez que comme toujours avec les blocs dans Kotlin, vous pouvez supprimer l'argument et utiliser it
:
ifNotNull(obj.item) {
doSomething(it)
}
Mais si le bloc fait plus de 1 à 2 lignes, il est probablement préférable d'être explicite.
C'est aussi similaire à Swift que je pourrais le trouver.
Il existe un moyen similaire dans kotlin pour obtenir le style if-let de Swift
if (val a = b) {
a.doFirst()
a.doSecond()
}
Vous pouvez également attribuer plusieurs valeurs Nullable
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
Ce type d'approche sera plus approprié si les valeurs Nullable sont utilisées plus d'une fois. À mon avis, cela aide du point de vue des performances car la valeur nullable ne sera vérifiée qu'une seule fois.
source: Discussion de Kotlin
J'ajoute cette réponse pour clarifier la réponse acceptée car elle est trop grande pour un commentaire.
Le modèle général ici est que vous pouvez utiliser n'importe quelle combinaison des fonctions de portée disponibles dans Kotlin séparées par l' opérateur Elvis comme ceci:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
Par exemple:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
a
n'est pas accessible à l'intérieurlet
et dans lerun
bloc.