Was entspricht diesem Ausdruck in Kotlin?
a ? b : c
Dies ist kein gültiger Code in Kotlin.
Was entspricht diesem Ausdruck in Kotlin?
a ? b : c
Dies ist kein gültiger Code in Kotlin.
Antworten:
In Kotlin sind if
Anweisungen Ausdrücke. Der folgende Code ist also äquivalent:
if (a) b else c
Die Unterscheidung zwischen Ausdruck und Aussage ist hier wichtig. Bildet in Java / C # / JavaScript if
eine Anweisung, dh, sie wird nicht in einen Wert aufgelöst. Genauer gesagt können Sie es keiner Variablen zuweisen.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Wenn Sie aus einer Sprache kommen, in der if
es sich um eine Aussage handelt, mag dies unnatürlich erscheinen, aber dieses Gefühl sollte bald nachlassen.
when
.
x = a==b
b + if (a) c else d
vs. b + (c if (a) else d)
Letzteres erfordert zusätzliche Klammern. weil c
ist nicht von der Bedingung und eingeschlossen else
.
Sie könnten Ihre eigene definieren Boolean
Erweiterungsfunktion , dass die Renditen , null
wenn die Boolean
ist false
eine Struktur ähnlich den ternären Operator zur Verfügung zu stellen:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Dies würde einen a ? b : c
Ausdruck a then b ?: c
wie folgt übersetzen lassen :
println(condition then "yes" ?: "no")
Update: Aber um einen Java-ähnlichen bedingten Wechsel durchzuführen, benötigen Sie so etwas
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
Achten Sie auf das Lambda. Die Berechnung des Inhalts sollte verschoben werden, bis wir sicher condition
sind , dass dies der Fall isttrue
Dieser sieht ungeschickt aus, weshalb eine stark nachgefragte Anforderung besteht, den ternären Java-Operator nach Kotlin zu portieren
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
?:
Betreiber hier elvis-operator
: kotlinlang.org/docs/reference/null-safety.html#elvis-operator
if (a) b else c
ist das, was Sie anstelle des ternären Operatorausdrucks verwenden können a ? b : c
.
In Kotlin, viele Steueranweisungen einschließlich if
, when
oder sogar try
kann verwendet werden als Ausdrücke . Dies bedeutet, dass diese ein Ergebnis haben können, das einer Variablen zugewiesen, von einer Funktion usw. zurückgegeben werden kann.
Aufgrund von Kotlins Ausdrücken benötigt die Sprache den ternären Operator nicht wirklich .
if (a) b else c
ist das, was Sie anstelle des ternären Operatorausdrucks verwenden können a ? b : c
.
Ich denke, die Idee ist, dass der frühere Ausdruck besser lesbar ist, da jeder weiß, was er ifelse
tut, während er ? :
eher unklar ist, wenn Sie mit der Syntax noch nicht vertraut sind.
Trotzdem muss ich zugeben, dass ich oft den bequemeren ternären Operator vermisse .
Andere Alternativen
wann
Möglicherweise werden auch when
Konstrukte in Kotlin verwendet, wenn die Bedingungen überprüft werden. Es ist auch eine Möglichkeit, If-else-Kaskaden auf alternative Weise auszudrücken. Das Folgende entspricht dem OTs-Beispiel.
when(a) {
true -> b
false -> c
}
Erweiterungen
Wie viele gute Beispiele ( Kotlin Ternary Conditional Operator ) in den anderen Antworten zeigen, können Erweiterungen auch bei der Lösung Ihres Anwendungsfalls hilfreich sein.
Für mich selbst benutze ich folgende Erweiterungsfunktionen:
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
Zuerst wird der angegebene Standardwert zurückgegeben, falls das Objekt gleich null ist. Zweitens wird der Ausdruck, der in Lambda bereitgestellt wird, im selben Fall bewertet.
Verwendungszweck:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Persönlich für mich Code oben besser lesbar als if
Konstruktion Inlining
e.getMessage() ?: "unknown"
. Die zweite kann ausgedrückt werden alsobj?.lastMessage?.timestamp ?: { Date() }()
Java entspricht dem ternären Operator
a ? b : c
ist eine einfache IF in Kotlin in einer Zeile
if(a) b else c
Es gibt keinen ternären Operator (Bedingung? dann: sonst), da gewöhnlich, wenn in dieser Rolle gut funktioniert.
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Sonderfall für den Nullvergleich
Sie können den Elvis-Operator verwenden
if ( a != null ) a else b
// equivalent to
a ?: b
In Kotlin gibt es keinen ternären Operator , da der if else
Block einen Wert zurückgibt
Sie können also val max = if (a > b) a else b
Folgendes tun:
anstelle von Javamax = (a > b) ? b : c
Wir können auch when
Konstruktion verwenden, es gibt auch Wert zurück:
val max = when(a > b) {
true -> a
false -> b
}
Hier ist der Link zur Kotlin-Dokumentation: Kontrollfluss: wenn, wann, für, während
In Kotlin
if
ist ein Ausdruck, dh er gibt einen Wert zurück. Daher gibt es keinen ternären Operator(condition ? then : else)
, da normal, wenn in dieser Rolle gut funktioniert. manuelle Quelle von hier
// 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
Einige Eckfälle werden in anderen Antworten nicht erwähnt.
Seit dem Erscheinen von takeIf in Kotlin 1.1 kann der ternäre Operator a ? b : c
auch folgendermaßen ausgedrückt werden:
b.takeIf { a } ?: c
Dies wird noch kürzer, wenn c ist null
:
b.takeIf { a }
Beachten Sie auch, dass in der Java-Welt typische Null-Checks wie das value != null ? value : defaultValue
Übersetzen im ideomatischen Kotlin in Just value ?: defaultValue
.
Ähnliches a != null ? b : c
kann übersetzt werden a?.let { b } ?: c
.
b.takeIf { a } ?: c
kürzer und lesbarer als if (a) b else c
? Der Terneray-Operator ist sicherlich ein fehlendes Feature in Kotlin, da Variablennamen und die Bedingung lang sein können und Sie die schlechte Zeile teilen können
takeIf
immer der wahre Fall bewertet wird (hier a
). Dieser Ausdruck kann nicht nur nutzlos berechnet werden, wenn a
er falsch ist, sondern Sie können auch nicht von Smart Casts à la profitieren if (a is Int) { a + 3 }
.
{ a }
ist ein träge ausgewertetes Lambda.
b
)". Aber auch { a }
wenn es faul ist, muss es ausgewertet werden, um das Ergebnis des Ausdrucks zu bestimmen.
Schauen Sie sich die Dokumente an :
Wenn in Kotlin ein Ausdruck vorhanden ist, gibt er einen Wert zurück. Daher gibt es keinen ternären Operator (Bedingung? Dann: sonst), weil gewöhnlich, wenn in dieser Rolle gut funktioniert.
Java
int temp = a ? b : c;
Entspricht Kotlin:
var temp = if (a) b else c
AUFGABE :
Betrachten wir das folgende Beispiel:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Wir brauchen das folgende Äquivalent in Kotlin:
return (! answer.isSuccessful ())
?
"falsch":
answer.body (). string ()
LÖSUNGEN :
1.a . Sie können if-expression
in Kotlin verwenden:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.b . Es kann viel besser sein, wenn Sie dies umdrehen if-expression
(lassen Sie es uns ohne tun not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 . Kotlins Elvis-Betreiber ?:
kann noch besser arbeiten:
return answer.body()?.string() ?: "wrong"
3 . Oder verwenden Sie ein Extension function
für die entsprechende Answer
Klasse:
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
4 . Mit dem können Extension function
Sie einen Code reduzieren dank Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
5 . Oder verwenden Sie einfach den when
Operator:
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
Hoffe das hilft.
Ersetzt den Switch-Operator von C-ähnlichen Sprachen. In der einfachsten Form sieht es so aus
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
eine Aussage, keinen Ausdruck. Ein relevanterer Vergleich mit ternären bedingten Ausdrücken wäre, dass jeder Zweig einen Wert zurückgibt, so dass der gesamte When-Ausdruck einen Wert ergibt (wie dies bei ternären Bedingungen der Fall ist).
In Kotlin gibt es keinen ternären Operator. Es scheint auf den ersten Blick problematisch. Aber denken Sie, wir können es mit der Inline-if-else-Anweisung tun, da dies hier Ausdruck ist. Einfach müssen wir tun -
var number = if(n>0) "Positive" else "Negetive"
Hier können wir sonst zu viele blockieren, wie wir brauchen. Mögen-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Diese Zeile ist also so einfach und gut lesbar als der ternäre Operator. Wenn wir in Java mehr als einen ternären Operator verwenden, scheint dies schrecklich. Aber hier haben wir eine klare Syntax. Auch wir können es in mehreren Zeilen schreiben.
Sie können var a= if (a) b else c
anstelle des ternären Operators verwenden.
Ein weiteres gutes Konzept von Kotlin ist Elvis Operater. Sie müssen nicht jedes Mal null überprüfen.
val l = b?.length ?: -1
Dies gibt die Länge zurück, wenn b nicht null ist, andernfalls wird die Anweisung auf der rechten Seite ausgeführt.
Wie Drew Noakes zitiert, verwendet Kotlin die if-Anweisung als Ausdruck, sodass ein ternärer bedingter Operator nicht mehr erforderlich ist.
Mit der Erweiterungsfunktion und der Infix-Überladung können Sie dies jedoch selbst implementieren. Hier ein Beispiel
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
}
dann benutze es so
val grade = 90
val clazz = (grade > 80) then "A" or "B"
Ein weiterer interessanter Ansatz wäre when
:
when(a) {
true -> b
false -> b
}
Kann in einigen komplexeren Szenarien sehr praktisch sein. Und ehrlich gesagt ist es für mich lesbarer alsif ... else ...
In Kotlin kann man das auf viele Arten machen
Verwenden von if
if(a) b else c
Verwenden wann
when (a) {
true -> print("value b")
false -> print("value c")
else -> {
print("default return in any other case")
}
}
Null Sicherheit
val a = b ?: c
Es gibt keine ternäre Operation in Kotlin, aber es gibt einige unterhaltsame Möglichkeiten, dies zu umgehen. Wie andere betont haben, würde eine direkte Übersetzung in Kotlin folgendermaßen aussehen:
val x = if (condition) result1 else result2
Aber ich persönlich denke, das kann etwas unübersichtlich und schwer zu lesen sein. In die Bibliothek sind einige andere Optionen integriert. Sie können takeIf {} mit einem elvis-Operator verwenden:
val x = result1.takeIf { condition } ?: result2
Dort passiert, dass der Befehl takeIf {} entweder Ihr Ergebnis1 oder null zurückgibt und der elvis-Operator die Option null verarbeitet. Es gibt einige zusätzliche Optionen, takeUnless {}, zum Beispiel:
val x = result1.takeUnless { condition } ?: result2
Die Sprache ist klar, Sie wissen, was das tut.
Wenn es sich um eine häufig verwendete Bedingung handelt, können Sie auch eine unterhaltsame Methode wie die Verwendung einer Inline-Erweiterungsmethode verwenden. Nehmen wir an, wir möchten beispielsweise ein Spielergebnis als Int verfolgen und immer 0 zurückgeben, wenn eine bestimmte Bedingung nicht erfüllt ist:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Ok, das scheint hässlich. Aber überlegen Sie, wie es aussieht, wenn es verwendet wird:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Wie Sie sehen können, bietet Kotlin viel Flexibilität bei der Auswahl Ihres Codes. Es gibt unzählige Variationen meiner Beispiele und wahrscheinlich Wege, die ich noch nicht einmal entdeckt habe. Ich hoffe das hilft!
takeIf
ist meine Lieblingsoption in der Tat sehr elegant.
Denken Sie daran, dass der ternäre Operator und der Elvis-Operator in Kotlin im Gegensatz zu vielen gängigen Sprachen unterschiedliche Bedeutungen haben. Wenn expression? value1: value2
Sie dies tun, würde der Kotlin- Compiler im Gegensatz zu jeder anderen Sprache schlechte Worte liefern , da es in Kotlin keinen ternären Operator gibt, wie in den offiziellen Dokumenten erwähnt . Der Grund dafür ist, dass die Anweisungen if, when und try-catch selbst Werte zurückgeben.
Tun expression? value1: value2
kann also durch ersetzt werden
val max = wenn (a> b) drucken ("Wähle a") sonst drucke ("Wähle b")
Der Elvis Operator dass Kotlin hat, funktioniert nur im Fall von Nullable - Variablen ex .:
Wenn ich so etwas tun
value3 = value1 ?: value2
dann , wenn Wert1 ist null dann Wert2 sonst zurückgegeben werden Wert1 würden zurückgegeben.
Aus diesen Antworten kann ein klareres Verständnis erzielt werden .
Sie können if
hierfür in Kotlin einen Ausdruck verwenden. In Kotlin if
ist ein Ausdruck mit einem Ergebniswert. Also können wir in Kotlin schreiben
fun max(a: Int, b: Int) = if (a > b) a else b
und in Java können wir dasselbe erreichen, aber mit größerem Code
int max(int a, int b) {
return a > b ? a : b
}
Wenn Sie die Standardnotation nicht verwenden, können Sie sie auch mithilfe eines Infixes wie folgt erstellen / simulieren :
Erstellen Sie eine Klasse, um Ihr Ziel und Ergebnis zu halten:
data class Ternary<T>(val target: T, val result: Boolean)
Erstellen Sie einige Infix-Funktionen, um eine ternäre Operation zu simulieren
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
}
Dann können Sie es folgendermaßen verwenden:
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"
Ein weiterer kurzer Ansatz
val value : String = "Kotlin"
value ?: ""
Hier prüft kotlin selbst den Nullwert und wenn es null ist, übergibt es einen leeren Zeichenfolgenwert.
Warum sollte man so etwas benutzen:
when(a) {
true -> b
false -> b
}
wenn Sie so etwas tatsächlich verwenden können ( a
ist in diesem Fall boolesch):
when {
a -> b
else -> b
}
? and :
widerspricht eher der Deklaration nullable / type als einer Typprüfung. Abgesehen davon sehe ich keinen Grund. Ich denke, jemand hätte definitiv darüber nachgedacht, wenn es eine Inline-If-else-Zustandsprüfung gibt. Lassen Sie uns abwarten und in zukünftigen Versionen sehen.
Wenn Sie mit apply () arbeiten, scheint let sehr praktisch zu sein, wenn Sie mit ternären Operationen arbeiten, da es eleganter ist und Ihnen Raum gibt
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
Mit den folgenden Infix-Funktionen kann ich viele gängige Anwendungsfälle so behandeln, wie es in Python möglich ist:
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
In Kotlin gibt es keinen ternären Operator. Die beiden am häufigsten abgeschlossenen Fälle sind:
val a = true if(a) print("A is true") else print("A is false")
Wenn der Ausdruck links von ?: Nicht null ist, gibt der elvis-Operator ihn zurück, andernfalls gibt er den Ausdruck rechts zurück. Beachten Sie, dass der Ausdruck auf der rechten Seite nur ausgewertet wird, wenn der Ausdruck auf der linken Seite null ist.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
Beispiel: var energy: Int = data? .get (position)?. energy? .toInt () ?: 0
In kotlin, wenn Sie ?: Verwenden , funktioniert es so, als ob die Anweisung dann null zurückgibt ?: 0 nimmt 0 oder was auch immer Sie auf dieser Seite geschrieben haben.
In Kotlin können Sie die ternäre Operation folgendermaßen verwenden: val x = if(a) "add b" else "add c"
Nach einigen Recherchen anderer Ideen habe ich den folgenden ternären Operator abgeleitet:
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
Beispiel ( hier ausführen ):
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")
}
}
Diese Version ist fließend und steht nicht in Konflikt mit dem Null-Koaleszenz-Operator.
then
anstelle von lautet yes
.