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:
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:
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
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
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.
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