Ternäre Operation

Erfahrene Entwickler, die mit C/C++ vertraut sind, kennen alle die ternäre Operation a ? b : c. Die Verwendung dieser Syntax zum Ersetzen einfacher bedingter Anweisungen kann den Code so prägnant wie möglich halten, ohne ihn schwerer lesbar zu machen.

int a, b, ret;
//if-else
if (a > b)
    ret = a;
else
    ret = b;

//三目运算符
ret = a > b ? a : b;

Ternäre Operation in Lua

Die native Semantik von Lua implementiert keine ternäre Operation; sie wird üblicherweise mit den logischen Operatoren and und or simuliert.

In Lua verwenden sowohl and als auch or die "Kurzschlussauswertung", was bedeutet, dass sie den zweiten Operanden nur auswerten, wenn es notwendig ist. ("Programming in Lua")

local a, b, ret;
ret = a > b and a or b

Alle Möglichkeiten aufzählen:

Wenn a > b:

a > b and a –> true 
a or b –> a

Wenn a <= b:

a > b and a –> false 
a or b –> b

Perfekt!

Fallstricke des ternären Operators in Lua

Nach dem Prinzip, vom Speziellen zum Allgemeinen zu gehen:

  • Die allgemeine Form der ternären Operation a ? b : c

    a = true, Ergebnis ist b
    a = false, Ergebnis ist c

  • Entspricht a and b or c in Lua

    • b = true
      • a = true
        • a and b –> true
        • b or c –> b
      • a = false
        • a and b –> false
        • b or c –> c
    • b = false
      • a = true
        • a and b –> false
        • b or c –> c
      • a = false
        • a and b –> false
        • b or c –> c

Man kann sehen, dass wenn b = false, das in Lua simulierte a and b or c immer c zurückgibt und das ursprüngliche Verhalten des ternären Operators nicht wiederherstellen kann.

"Programming in Lua" empfiehlt ebenfalls, if-else zu verwenden, um diese Situation zu vermeiden.

Verallgemeinerung von a and b or c

Gibt es eine Möglichkeit, das Problem zu lösen, dass b = false fehlschlägt?

Das erinnert mich an eine gängige Prüfungsfrage in C: Schreiben Sie eine Makrodefinition, die den kleineren von zwei Werten zurückgibt.

Als ich dieses Problem zum ersten Mal in der Schule sah, war meine erste Reaktion:

#define MIN(A,B) A < B ? A : B

Allerdings kann diese Schreibweise in vielen verschachtelten Verwendungskontexten keine korrekten Ergebnisse zurückgeben. Zum Beispiel: 2 * MIN(3, 4) wird zu 2 * 3 < 4 ? 3 : 4 = 6 < 4 ? 3 : 4 erweitert, und das Ergebnis ist 4.
Ein eher "Ingenieur"-artiger Schreibstil ist:

#define MIN(A,B) ((A) < (B) ? (A) : (B))

Neugierige Leser können aufverweisen: Die korrekte Art, eine Makrodefinition zu schreiben, Makrodefinition der ternären Operation

Ausgehend von diesem Beispiel begann ich zu überlegen: Wie können wir sicherstellen, dass b in a and b or c wahr ist, oder dass b keine Mehrdeutigkeit verursacht?

  • and hat eine höhere Operatorpriorität als or; eine bloße Änderung der Operationsreihenfolge hilft nicht.
  • Dann dachte ich an die Allzwecktabelle in Lua. Können wir a, b und c alle in Tabellen packen, um das Vorhandensein von b zu ändern? Beachten Sie, dass {nil} ebenfalls ein truthy-Objekt ist.
    Ersetzen Sie a, b, c alle durch Tabellen: {a} and {b} or {c}.
  • In der ternären Operation ist a die Bedingung und das Ergebnis ist b oder c. Tatsächlich muss a nicht in eine Tabelle gesetzt werden; andernfalls wäre {a} immer wahr, wodurch der Sinn der Bedingung verloren geht. Und {b} or
    das Ergebnis von {c} ist notwendigerweise eine Tabelle, und diese Tabelle enthält nur ein Element. Dann kann darauf zugegriffen werden durch
  • Zusammenfassend ist eine allgemeinere Lua-Ternäroperation: (a and {b} or {c})

Zusammenfassung

Zugegeben, um die Form der ternären Operation in Lua zu kennen, kann man einfach danach suchen und die gewünschte Antwort finden. Der obige Argumentationsprozess steht etwas im Verdacht, die Antwort bereits zu kennen und bewusst darauf hinzusteuern. Ich bin jedoch fest davon überzeugt, dass beim Beweisen eines Problems die Schlussfolgerung nicht das Wichtigste ist; der Argumentationsprozess ist es. Dieser Artikel versucht, die Herleitung der verallgemeinerten Lua-Ternäroperation allein auf der Grundlage meines oberflächlichen Verständnisses von Lua zu rekonstruieren. Wenn es einen besseren Argumentationsprozess gibt, können wir uns austauschen.

Quelle: https://blog.csdn.net/u010832643/article/details/77546887