Ich schreibe einen Code-Generator, der Scala-Ausgabe erzeugt.
Ich muss einen ternären Operator so emulieren, dass die Token zu '?' bleiben intakt.
z.B. Konvertiere den Ausdruck c ? p : q
in c something
. Das einfache if(c) p else q
scheitert an meinen Kriterien, da if(
vor c
gesetzt werden muss.
Mein erster Versuch (immer noch mit c / p / q wie oben) ist
%Vor%Eine andere Option, die ich fand, war:
%Vor%was mir erlaubt zu schreiben:
%Vor%Ich mag das allgemeine Aussehen der zweiten Option, aber gibt es eine Möglichkeit, es weniger ausführlich zu machen?
Danke
Obwohl die Syntax nicht in der erwarteten Reihenfolge ausgewertet wird - sie bindet die Bedingung an die erste Option! - können Sie Ihren eigenen ternären Operator wie folgt erstellen:
%Vor% Der Trick besteht darin, ?
als Methode für ein MakeIfTrue
-Objekt zu interpretieren, das die Bedingung an das Objekt bindet, das im "wahren" Fall zurückgegeben werden soll. Das resultierende IfTrue
-Objekt verwendet nun die |
-Methode als Anfrage, um die Bedingung auszuwerten, wobei die gespeicherte True-Option zurückgegeben wird, wenn die Bedingung wahr ist, oder die gerade übergebene, wenn sie falsch ist.
Beachten Sie, dass ich Sachen wie => A
anstatt nur A
- Namensparameter verwendet habe, um den Ausdruck nicht auszuwerten, es sei denn, er wird tatsächlich verwendet. Daher werten Sie nur die Seite aus, die Sie tatsächlich benötigen (genau wie eine if-Anweisung).
Sehen wir es in Aktion:
%Vor% (P.S. Um Verwechslungen mit der Actor-Bibliothek ?
zu vermeiden, sollten Sie es wahrscheinlich etwas anderes nennen wie |?
.)
Lass es uns einfach machen:
Java:
%Vor%Scala:
%Vor%Neben der Einfachheit ist es klar und schnell, weil: Sie keine Objekte zuweisen, die Sie nicht benötigen, hält den Garbage Collector aus der Gleichung heraus (wie es immer sein sollte) und verwendet besser Prozessor-Caches.
Sie könnten so etwas verwenden
%Vor% Dieser Code konvertiert jeden booleschen Wert in einen anonymen Typ mit einer Methode namens ?
. Abhängig vom Wert des booleschen Werts gibt diese Methode entweder TernarySecond
oder TernaryThird
zurück. Beide haben eine Methode namens >
, die den zweiten Operanden bzw. den dritten Operanden zurückgibt.
Ternärer Operator, der meine Verbesserung zu den besten Implementierungen von Rex Kerr und Michel Krämer hinzufügt:
.
%Vor% Beachten Sie, dass die Verbesserung gegenüber if else
nicht nur die 6 gespeicherten Zeichen ist. Da die Syntax von Scala IDE für Schlüsselworte identisch ist (z. B. violett) für if
, else
, null
und true
, gibt es in einigen Fällen einen besseren Kontrast (was durch die Syntaxfarbe unten nicht gezeigt wird) wie derzeit auf dieser Website dargestellt):
Tags und Links scala language-features scala-2.8