[JAVA] Kotlin n'a pas d'opérateur ternaire (opérateur conditionnel)

Opérateur Kotlin et ternaire (opérateur conditionnel)

Avec le support officiel de Google pour Kotlin comme langage de développement Android, Kotlin a été un sujet brûlant ces derniers temps, mais Kotlin n'a pas d'opérateur ternaire.

val max = a > b ? a : b // NG

Au lieu de cela, Kotlin if est traité comme une expression, vous pouvez donc écrire:

val max = if (a > b) a else b

Mais n'est-il pas gênant que Java ait un opérateur ternaire mais pas Kotlin? : thinking_face: Donc cette fois, j'aimerais forcer quelque chose comme un opérateur ternaire: muscle:

Définir un opérateur ternaire

Vous ne pouvez pas utiliser Surcharge d'opérateur car Kotlin n'a pas les opérateurs ? Et :.

Cependant, vous pouvez utiliser ʻinfix` pour définir votre propre opérateur (à quoi ressemble). https://kotlinlang.org/docs/reference/functions.html#infix-notation

Cette fois, définissez la classe et la fonction infixe comme suit.

data class TernaryOperation<out T>(val condition: Boolean, val value: T)

infix fun <T> Boolean.`?`(other: T) = TernaryOperation<T>(this, other)
infix fun <T> TernaryOperation<T>.`:`(other: T) = if (this.condition) this.value else other

? Et : ne peuvent pas être utilisés comme noms de fonction, ils sont donc placés entre guillemets. Cependant, bien que je puisse utiliser ? '', Je ne pouvais pas utiliser : pour une raison quelconque, alors j'ai choisi: `` (pleine largeur). De plus, dans Kotlin, vous pouvez utiliser le japonais pour les noms de fonctions comme en Java, mais `? Vous ne pouvez pas utiliser «ou» ou «:».

Cela ressemble à ceci lorsque vous utilisez la fonction définie ci-dessus.

val max = (a > b) `?` a `:` b

C'est comme ça: sweat_smile:

Différence avec l'opérateur ternaire Java

Priorité de l'opérateur

La fonction d'infixe de Kotlin a une priorité plus élevée que l'opérateur de comparaison. https://kotlinlang.org/docs/reference/grammar.html#precedence

En revanche, les opérateurs ternaires Java ont une priorité plus faible que les opérateurs de comparaison. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Par conséquent, si vous souhaitez utiliser un opérateur de comparaison, etc., comme l'opérateur ternaire créé cette fois, vous devez mettre l'expression conditionnelle entre parenthèses.

Java


int max = a > b ? a : b; // OK

Kotlin


val max = a > b `?` a `:` b // NG

val max = (a > b) `?` a `:` b // OK
val max = (a > b) `?` a + 3 `:` b - 5 // OK

Évaluation de la formule

J'ai remarqué dans le commentaire de saka1029. Merci: arc:

Étant donné que le type d'opérateur ternaire créé cette fois-ci transmet une valeur, les deux valeurs seront évaluées indépendamment de la véracité de la condition.

Java


int value = array.length > 0 ? array[0] : -1; // OK

Kotlin


val value = array.isNotEmpty() `?` array[0] `:` -1 //ArrayIndexOutOfBoundsException lorsque le tableau est vide

Pour éviter cela, vous devez faire le type () -> T au lieu du type T, mais ce n'est plus différent de if expression: sweat_smile:

data class TernaryOperation<out T>(val condition: Boolean, val value: () -> T)

infix fun <T> Boolean.`?`(other: () -> T) = TernaryOperation<T>(this, other)
infix fun <T> TernaryOperation<T>.`:`(other: () -> T) = if (this.condition) this.value() else other()

val value = array.isNotEmpty() `?` { array[0] } `:` { -1 } // OK

Modèles utilisant l'opérateur Elvis

Définissez la fonction d'infixe suivante.

infix fun <T> Boolean.then(other: T) = if (this) other else null

En utilisant l'opérateur Elvis, vous pouvez l'écrire comme un opérateur ternaire comme suit.

val max = (a > b) then a ?: b

Cependant, si vous utilisez null pour la valeur quand true, ce sera toujours la valeur quand elle est false: cry:

val body = response.isError() then null ?: response.body // always response.body

De plus, comme auparavant, il y a des problèmes prioritaires et des problèmes d'évaluation des expressions.

Résumé

J'ai essayé de le fabriquer avec du matériel, mais après tout, ce n'est pas pratique: la sueur: J'utilise aussi beaucoup Python, donc je suis encore nouveau dans l'écriture des opérateurs ternaires de Kotlin: sob:

Si vous avez des impressions ou des opinions, veuillez commenter: arc:

Recommended Posts

Kotlin n'a pas d'opérateur ternaire (opérateur conditionnel)
Opérateur ternaire de référence
Branche conditionnelle de Ruby. if, opérateur conditionnel (opérateur ternaire), sauf si, cas
Kotlin 1.3.50 est sorti !!
À propos de l'opérateur ternaire
Une histoire confuse sur un opérateur ternaire avec plusieurs expressions conditionnelles
L'opérateur ternaire est-il mauvais?