Quel est l'équivalent de cette expression dans Kotlin?
a ? b : c
Ce n'est pas un code valide dans Kotlin.
Quel est l'équivalent de cette expression dans Kotlin?
a ? b : c
Ce n'est pas un code valide dans Kotlin.
Réponses:
Dans Kotlin, les if
déclarations sont des expressions. Le code suivant est donc équivalent:
if (a) b else c
La distinction entre expression et déclaration est ici importante. En Java / C # / JavaScript, if
forme une instruction, ce qui signifie qu'elle ne se résout pas en une valeur. Plus concrètement, vous ne pouvez pas l'affecter à une variable.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Si vous venez d'une langue où if
est une déclaration, cela peut sembler contre nature, mais ce sentiment devrait bientôt disparaître.
when
.
x = a==b
b + if (a) c else d
contre b + (c if (a) else d)
ce dernier nécessite des parenthèses supplémentaires. car c
n'est pas entouré par la condition et else
.
Vous pouvez définir votre propre Boolean
fonction d'extension qui retourne null
lorsque le Boolean
est false
de fournir une structure similaire à l'opérateur ternaire:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Cela ferait a ? b : c
traduire une expression a then b ?: c
comme suit:
println(condition then "yes" ?: "no")
Mise à jour: Mais pour faire un changement conditionnel de type Java, vous aurez besoin de quelque chose comme ça
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
faites attention à la lambda. le calcul du contenu devrait être reportée jusqu'à ce que nous nous assurons condition
esttrue
Celui-ci a l'air maladroit, c'est pourquoi il existe une demande très élevée pour porter l'opérateur ternaire Java dans Kotlin
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
?:
opérateur ici est elvis-operator
: kotlinlang.org/docs/reference/null-safety.html#elvis-operator
if (a) b else c
est ce que vous pouvez utiliser à la place de l'expression d'opérateur ternaire a ? b : c
.
Dans Kotlin, de nombreuses déclarations de contrôle , y compris if
, when
ou même try
peut être utilisé comme expressions . Cela signifie que ceux-ci peuvent avoir un résultat qui peut être affecté à une variable, renvoyé par une fonction, etc.
Du fait des expressions de Kotlin, le langage n'a pas vraiment besoin de l'opérateur ternaire .
if (a) b else c
est ce que vous pouvez utiliser à la place de l'expression d'opérateur ternaire a ? b : c
.
Je pense que l'idée est que l'ancienne expression est plus lisible car tout le monde sait ce que ifelse
fait, alors qu'elle ? :
n'est pas claire si vous n'êtes pas déjà familier avec la syntaxe.
Néanmoins, je dois admettre que je manque souvent l'opérateur ternaire le plus pratique.
Autres alternatives
quand
Vous pouvez également voir des when
constructions utilisées dans Kotlin lorsque les conditions sont vérifiées. C'est aussi un moyen d'exprimer les cascades if-else d'une manière alternative. Ce qui suit correspond à l'exemple des OT.
when(a) {
true -> b
false -> c
}
Extensions
Comme le montrent de nombreux bons exemples ( opérateur conditionnel ternaire de Kotlin ) dans les autres réponses, les extensions peuvent également vous aider à résoudre votre cas d'utilisation.
Pour moi, j'utilise les fonctions d'extension suivantes:
fun T?.or<T>(default: T): T = if (this == null) default else this
fun T?.or<T>(compute: () -> T): T = if (this == null) compute() else this
Le premier retournera la valeur par défaut fournie dans le cas où l'objet est égal à null. Le second évaluera l'expression fournie dans lambda dans le même cas.
Usage:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Personnellement, le code ci-dessus est plus lisible que la if
construction en ligne
e.getMessage() ?: "unknown"
. Le second peut être exprimé comme obj?.lastMessage?.timestamp ?: { Date() }()
L'équivalent Java de l'opérateur ternaire
a ? b : c
est un simple IF dans Kotlin en une seule ligne
if(a) b else c
il n'y a pas d'opérateur ternaire (condition? alors: else), car ordinaire si fonctionne bien dans ce rôle.
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Cas particulier pour la comparaison Null
vous pouvez utiliser l' opérateur Elvis
if ( a != null ) a else b
// equivalent to
a ?: b
Il n'y a pas d'opérateur ternaire dans kotlin, car le if else
bloc renvoie une valeur
vous pouvez donc faire:
val max = if (a > b) a else b
au lieu de javamax = (a > b) ? b : c
On peut aussi utiliser la when
construction, ça renvoie aussi de la valeur:
val max = when(a > b) {
true -> a
false -> b
}
Voici le lien pour la documentation de kotlin: Flux de contrôle: if, when, for, while
Dans Kotlin,
if
est une expression, c'est-à-dire qu'elle renvoie une valeur. Il n'y a donc pas d'opérateur ternaire(condition ? then : else)
, car ordinaire si fonctionne bien dans ce rôle. source manuelle d'ici
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
Quelques cas d'angle non mentionnés dans d'autres réponses.
Depuis l'apparition de takeIf dans Kotlin 1.1, l'opérateur ternaire a ? b : c
peut également être exprimé comme ceci:
b.takeIf { a } ?: c
Cela devient encore plus court dans le cas où c est null
:
b.takeIf { a }
Notez également que dans le monde Java, les vérifications nulles comme value != null ? value : defaultValue
traduire dans Kotlin idéomatique en juste value ?: defaultValue
.
Similaire a != null ? b : c
peut être traduit en a?.let { b } ?: c
.
b.takeIf { a } ?: c
plus court et plus lisible que if (a) b else c
? L'opérateur de Terneray est certainement une fonctionnalité manquante dans Kotlin car les noms de variables et la condition peuvent être longs et vous obliger à diviser la ligne, ce qui est mauvais
takeIf
toujours évalue le cas réel (ici a
). Non seulement cette expression peut être calculée inutilement s'il a
se trouve qu'elle est fausse, mais vous ne pouvez pas bénéficier de modèles intelligents à la if (a is Int) { a + 3 }
.
{ a }
est un lambda évalué paresseusement.
b
)". Mais même { a }
, bien que paresseux, doit être évalué pour déterminer le résultat de l'expression.
Java
int temp = a ? b : c;
Équivalent à Kotlin:
var temp = if (a) b else c
TÂCHE :
Prenons l'exemple suivant:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Nous avons besoin de l'équivalent suivant dans Kotlin:
return (! answer.isSuccessful ())
?
"incorrect":
answer.body (). string ()
SOLUTIONS :
1.A . Vous pouvez utiliser if-expression
dans Kotlin:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.b . Cela peut être bien mieux si vous retournez ceci if-expression
(faisons-le sans not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 . L'opérateur Elvis de Kotlin ?:
peut faire un travail encore mieux:
return answer.body()?.string() ?: "wrong"
3 . Ou utilisez un Extension function
pour la Answer
classe correspondante :
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
4 . En utilisant le, Extension function
vous pouvez réduire un code grâce à Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
5 . Ou utilisez simplement l' when
opérateur:
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
J'espère que cela t'aides.
quand remplace l'opérateur de commutation des langages de type C. Dans sa forme la plus simple, cela ressemble à ceci
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
une déclaration, pas une expression. Une comparaison plus pertinente avec les expressions conditionnelles ternaires consisterait à ce que chaque branche renvoie une valeur, de sorte que l'expression when entière soit évaluée à une valeur (comme cela se produit avec les conditions ternaires).
Il n'y a pas d'opérateur ternaire à Kotlin. Cela semble problématique à première vue. Mais pensez que nous pouvons le faire avec l'instruction inline if else car c'est l'expression ici. Nous devons simplement faire -
var number = if(n>0) "Positive" else "Negetive"
Ici, nous pouvons le faire si nous en bloquons trop. Comme-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Cette ligne est donc tellement simple et beaucoup plus lisible que l'opérateur ternaire. lorsque nous utilisons plus d'un opérateur ternaire en java, cela semble horrible. Mais ici, nous avons une syntaxe claire. même nous pouvons également l'écrire sur plusieurs lignes.
Vous pouvez utiliser var a= if (a) b else c
à la place de l'opérateur ternaire.
Un autre bon concept de kotlin est l'opératrice Elvis. Vous n'avez pas besoin de vérifier null à chaque fois.
val l = b?.length ?: -1
Cela retournera la longueur si b n'est pas nul sinon il exécute l'instruction du côté droit.
comme l'a dit Drew Noakes, kotlin utilise l'instruction if comme expression, donc l'opérateur conditionnel ternaire n'est plus nécessaire,
mais avec la fonction d'extension et la surcharge des infixes, vous pouvez l'implémenter vous-même, voici un exemple
infix fun <T> Boolean.then(value: T?) = TernaryExpression(this, value)
class TernaryExpression<out T>(val flag: Boolean, val truly: T?) {
infix fun <T> or(falsy: T?) = if (flag) truly else falsy
}
puis utilisez-le comme ça
val grade = 90
val clazz = (grade > 80) then "A" or "B"
Une autre approche intéressante serait d'utiliser when
:
when(a) {
true -> b
false -> b
}
Peut être très pratique dans certains scénarios plus complexes. Et honnêtement, c'est plus lisible pour moi queif ... else ...
Vous pouvez le faire de nombreuses façons à Kotlin
Utilisation de if
if(a) b else c
Utiliser quand
when (a) {
true -> print("value b")
false -> print("value c")
else -> {
print("default return in any other case")
}
}
Sécurité nulle
val a = b ?: c
Il n'y a pas d'opération ternaire à Kotlin, mais il existe des façons amusantes de contourner cela. Comme d'autres l'ont souligné, une traduction directe dans Kotlin ressemblerait à ceci:
val x = if (condition) result1 else result2
Mais, personnellement, je pense que cela peut devenir un peu encombré et difficile à lire. Il existe d'autres options intégrées à la bibliothèque. Vous pouvez utiliser takeIf {} avec un opérateur elvis:
val x = result1.takeIf { condition } ?: result2
Ce qui se passe là-bas, c'est que la commande takeIf {} retourne votre résultat1 ou null, et l'opérateur elvis gère l'option null. Il y a quelques options supplémentaires, takeUnless {}, par exemple:
val x = result1.takeUnless { condition } ?: result2
Le langage est clair, vous savez ce que ça fait.
Si c'est une condition couramment utilisée, vous pouvez également faire quelque chose d'amusant comme utiliser une méthode d'extension en ligne. Supposons que nous voulons suivre un score de jeu comme un Int, par exemple, et nous voulons toujours retourner 0 si une condition donnée n'est pas remplie:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Ok, ça semble moche. Mais considérez à quoi il ressemble quand il est utilisé:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Comme vous pouvez le voir, Kotlin offre une grande flexibilité dans la façon dont vous choisissez d'exprimer votre code. Il existe d'innombrables variantes de mes exemples et probablement des façons que je n'ai même pas encore découvert. J'espère que ça aide!
takeIf
est mon option préférée en effet, très élégante.
Rappelez-vous que l' opérateur ternaire et l' opérateur Elvis ont des significations distinctes dans Kotlin contrairement à de nombreuses langues populaires. Faire expression? value1: value2
vous donnerait de mauvais mots par le compilateur Kotlin , contrairement à toute autre langue car il n'y a pas d'opérateur ternaire dans Kotlin comme mentionné dans les documents officiels . La raison en est que les instructions if, when et try-catch renvoient elles - mêmes des valeurs.
Donc, faire expression? value1: value2
peut être remplacé par
val max = if (a> b) print ("Choose a") else print ("Choose b")
L' opérateur Elvis que Kotlin a, ne fonctionne que dans le cas des variables annulable ex .:
Si je fais quelque chose comme ça
value3 = value1 ?: value2
alors si value1 est null alors value2 serait retourné sinon value1 serait retourné.
Une compréhension plus claire peut être obtenue à partir de ces réponses .
Vous pouvez utiliser l' if
expression pour cela dans Kotlin. Dans Kotlin if
est une expression avec une valeur de résultat. Donc, à Kotlin, nous pouvons écrire
fun max(a: Int, b: Int) = if (a > b) a else b
et en Java, nous pouvons réaliser la même chose mais avec un code plus grand
int max(int a, int b) {
return a > b ? a : b
}
Si vous ne savez pas quoi utiliser la notation standard, vous pouvez également la créer / simuler en utilisant infix avec quelque chose comme ceci:
créer une classe pour contenir votre cible et résultat:
data class Ternary<T>(val target: T, val result: Boolean)
créer des fonctions d'infixe pour simuler une opération ternaire
infix fun <T> Boolean.then(target: T): Ternary<T> {
return Ternary(target, this)
}
infix fun <T> Ternary<T>.or(target: T): T {
return if (this.result) this.target else target
}
Ensuite, vous pourrez l'utiliser comme ceci:
val collection: List<Int> = mutableListOf(1, 2, 3, 4)
var exampleOne = collection.isEmpty() then "yes" or "no"
var exampleTwo = (collection.isNotEmpty() && collection.contains(2)) then "yes" or "no"
var exampleThree = collection.contains(1) then "yes" or "no"
Une autre approche courte à utiliser
val value : String = "Kotlin"
value ?: ""
Ici, kotlin vérifie lui-même la valeur nulle et s'il est nul, il transmet une valeur de chaîne vide.
Pourquoi utiliserait-on quelque chose comme ça:
when(a) {
true -> b
false -> b
}
quand vous pouvez réellement utiliser quelque chose comme ça ( a
est booléen dans ce cas):
when {
a -> b
else -> b
}
? and :
contredit la déclaration nullable / type plutôt qu'une vérification de type. En dehors de cela, je ne vois aucune raison. Je pense que quelqu'un aurait certainement réfléchi, s'il y avait un contrôle conditionnel if-else en ligne. Attendons de voir dans les futures versions.
Lorsque vous travaillez avec apply (), laissez semble très pratique lorsqu'il s'agit d'opérations ternaires, car il est plus élégant et vous donne de la place
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
Avec les fonctions d'infixe suivantes, je peux couvrir de nombreux cas d'utilisation courants à peu près de la même manière que cela peut être fait en Python:
class TestKotlinTernaryConditionalOperator {
@Test
fun testAndOrInfixFunctions() {
Assertions.assertThat(true and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(false and "yes" or "no").isEqualTo("no")
Assertions.assertThat("A" and "yes" or "no").isEqualTo("yes")
Assertions.assertThat("" and "yes" or "no").isEqualTo("no")
Assertions.assertThat(1 and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(0 and "yes" or "no").isEqualTo("no")
Assertions.assertThat(Date() and "yes" or "no").isEqualTo("yes")
@Suppress("CAST_NEVER_SUCCEEDS")
Assertions.assertThat(null as Date? and "yes" or "no").isEqualTo("no")
}
}
infix fun <E> Boolean?.and(other: E?): E? = if (this == true) other else null
infix fun <E> CharSequence?.and(other: E?): E? = if (!(this ?: "").isEmpty()) other else null
infix fun <E> Number?.and(other: E?): E? = if (this?.toInt() ?: 0 != 0) other else null
infix fun <E> Any?.and(other: E?): E? = if (this != null) other else null
infix fun <E> E?.or(other: E?): E? = this ?: other
Il n'y a pas d'opérateur ternaire à Kotlin, les plus fermés sont les deux cas ci-dessous,
val a = true if(a) print("A is true") else print("A is false")
Si l'expression à gauche de?: N'est pas nulle, l'opérateur elvis la renvoie, sinon elle renvoie l'expression à droite. Notez que l'expression de droite n'est évaluée que si la gauche est nulle.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
exemple: var energy: Int = data? .get (position) ?. energy? .toInt ()?: 0
Dans kotlin si vous utilisez ?: Cela fonctionnera comme si l'instruction retournera null alors ?: 0 cela prendra 0 ou tout ce que vous avez écrit de ce côté.
Dans Kotlin, vous pouvez utiliser une opération ternaire comme celle-ci: val x = if(a) "add b" else "add c"
Après quelques recherches sur d'autres idées, j'ai dérivé l'opérateur ternaire suivant:
infix fun <T : Any> Boolean.yes(trueValue: T): T? = if (this) trueValue else null
infix fun <T : Any> T?.no(falseValue: T): T = this ?: falseValue
Exemple (exécutez ici ):
fun main() {
run {
val cond = true
val result = cond yes "True!" no "False!"
println("ternary test($cond): $result")
}
run {
val cond = false
val result = cond yes "True!" no "False!"
println("ternary test($cond): $result")
}
}
Cette version est courante et n'entre pas en conflit avec l'opérateur de coalescence nul.
then
au lieu de yes
.