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