[JAVA] Kotlin hat keinen ternären Operator (bedingter Operator)

Kotlin und ternärer Operator (bedingter Operator)

Mit Googles offizieller Unterstützung für Kotlin als Android-Entwicklungssprache war Kotlin in letzter Zeit ein heißes Thema, aber Kotlin hat keinen ternären Operator.

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

Stattdessen Kotlin wenn als Ausdruck behandelt wird, sodass Sie schreiben können:

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

Aber ist es nicht unpraktisch, dass Java einen ternären Operator hat, Kotlin jedoch nicht? : think_face: Dieses Mal möchte ich so etwas wie einen ternären Operator erzwingen: Muskel:

Definieren Sie einen ternären Operator

Sie können Operator overloading nicht verwenden, da Kotlin nicht über die Operatoren ? Und : verfügt.

Sie können jedoch "infix" verwenden, um Ihre eigenen Operatoren zu definieren (wie sie aussehen). https://kotlinlang.org/docs/reference/functions.html#infix-notation

Definieren Sie diesmal die Klassen- und Infixfunktion wie folgt.

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

? Und : können nicht als Funktionsnamen verwendet werden, daher sind sie in Anführungszeichen eingeschlossen. Obwohl ich `?` Verwenden konnte, konnte ich aus irgendeinem Grund nicht `:` verwenden, also entschied ich mich für `:` (in voller Breite). Auch in Kotlin können Sie Japanisch für Funktionsnamen wie in Java verwenden, aber `? Sie können nicht "oder" oder ":" verwenden.

Bei Verwendung der oben definierten Funktion sieht es so aus.

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

Es fühlt sich so an: heat_smile:

Unterschied zum ternären Java-Operator

Bedienerpriorität

Die Infix-Funktion von Kotlin hat eine höhere Priorität als der Vergleichsoperator. https://kotlinlang.org/docs/reference/grammar.html#precedence

Andererseits haben ternäre Java-Operatoren eine niedrigere Priorität als Vergleichsoperatoren. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Wenn Sie daher einen Vergleichsoperator usw. verwenden möchten, wie den diesmal erstellten ternären Operator, müssen Sie den bedingten Ausdruck in Klammern setzen.

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

Auswertung der Formel

Ich habe es im Kommentar von saka1029 bemerkt. Danke: Bogen:

Da der diesmal erstellte ternäre Operator einen Wert übergibt, werden beide Werte unabhängig von der Wahrheit der Bedingung ausgewertet.

Java


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

Kotlin


val value = array.isNotEmpty() `?` array[0] `:` -1 //ArrayIndexOutOfBoundsException, wenn das Array leer ist

Um dies zu vermeiden, müssen Sie den Typ () -> T anstelle des Typs T festlegen, aber er unterscheidet sich nicht mehr von if expression: heat_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

Muster, die den Elvis-Operator verwenden

Definieren Sie die folgende Infix-Funktion.

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

Mit dem Elvis-Operator können Sie ihn wie folgt wie einen ternären Operator schreiben.

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

Wenn Sie jedoch "null" für den Wert "true" verwenden, ist dies immer der Wert, wenn "false" lautet: cry:

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

Außerdem gibt es nach wie vor Prioritätsprobleme und Probleme bei der Bewertung von Ausdrücken.

Zusammenfassung

Ich habe versucht, es mit Material zu machen, aber es ist doch unpraktisch: Schweiß: Ich benutze auch viel Python, daher bin ich noch neu im Schreiben von Kotlins ternären Operatoren: sob:

Wenn Sie Eindrücke oder Meinungen haben, kommentieren Sie bitte: bow:

Recommended Posts

Kotlin hat keinen ternären Operator (bedingter Operator)
Referenz ternärer Operator
Bedingter Zweig von Ruby. if, bedingter Operator (ternärer Operator), es sei denn, case
Kotlin 1.3.50 wurde veröffentlicht !!
Über den ternären Operator
Eine verwirrte Geschichte über einen ternären Operator mit mehreren bedingten Ausdrücken
Ist der ternäre Operator schlecht?