Opération ternaire

Les vétérans familiers de C/C++ connaissent tous l'opération ternaire a ? b : c. Utiliser cette syntaxe pour remplacer des instructions conditionnelles simples permet de garder le code aussi concis que possible sans le rendre plus difficile à lire.

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

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

Opération ternaire en Lua

La sémantique native de Lua n'implémente pas d'opération ternaire ; elle est généralement simulée à l'aide des opérateurs logiques and et or.

En Lua, and et or utilisent tous deux l'« évaluation en court-circuit », ce qui signifie qu'ils n'évaluent le second opérande que lorsque c'est nécessaire. (« Programming in Lua »)

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

Énumérer toutes les possibilités :

Lorsque a > b :

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

Lorsque a <= b :

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

Parfait !

Pièges de l'opérateur ternaire en Lua

En suivant le principe qui consiste à aller du spécifique au général :

  • La forme générale de l'opération ternaire a ? b : c

    a = true, le résultat est b
    a = false, le résultat est c

  • Correspond à a and b or c en 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

On peut voir que lorsque b = false, le a and b or c simulé par Lua renvoie toujours c et ne peut pas restaurer le comportement d'origine de l'opérateur ternaire.

« Programming in Lua » recommande également d'utiliser if-else pour éviter cette situation.

Généralisation de a and b or c

Existe-t-il un moyen de résoudre le problème où b = false échoue ?

Cela me rappelle une question d'examen courante en langage C : écrire une définition de macro qui renvoie la plus petite de deux valeurs.

Quand j'ai vu ce problème pour la première fois à l'école, ma première réaction a été :

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

Cependant, ce type d'écriture ne peut pas renvoyer de résultats corrects dans de nombreux contextes d'utilisation imbriqués. Par exemple : 2 * MIN(3, 4) se développe en 2 * 3 < 4 ? 3 : 4 = 6 < 4 ? 3 : 4, et le résultat est 4.
Un style d’écriture plus « ingénieur » est :

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

Les lecteurs curieux peuvent se référer à: La bonne façon d’écrire une définition de macro, définition de macro de l’opération ternaire

À partir de cet exemple, j’ai commencé à réfléchir : comment garantir que b dans a and b or c est vrai, ou que b ne crée pas d’ambiguïté ?

  • and a une précédence d’opérateur supérieure à or ; le simple fait de changer l’ordre des opérations n’aide pas.
  • J’ai alors pensé à la table à tout faire de Lua. Peut-on mettre a, b et c tous dans des tables pour changer la présence de b ? Notez que {nil} est aussi un objet évalué comme vrai.
    Remplacez a, b, c tous par des tables : {a} and {b} or {c}.
  • Dans l’opération ternaire, a est la condition et le résultat est b or c. En fait, a n’a pas besoin d’être mis dans une table ; sinon {a} serait toujours vrai, ce qui ferait perdre le sens de la condition. Et {b} or
    le résultat de {c} est nécessairement une table, et cette table ne contient qu’un seul élément. On peut alors y accéder via
  • En résumé, une opération ternaire Lua plus généralisée est : (a and {b} or {c})

Résumé

Certes, pour connaître la forme de l’opération ternaire en Lua, il suffit de faire une recherche et de trouver la réponse souhaitée. Le raisonnement ci-dessus est quelque peu suspect : on pourrait croire que je connaissais déjà la réponse et que je m’orientais délibérément vers elle. Cependant, je crois fermement que, lorsqu’on démontre un problème, la conclusion n’est pas le plus important ; c’est le processus d’argumentation qui l’est. Cet article tente de reconstruire la dérivation de l’opération ternaire Lua généralisée en me fondant uniquement sur ma compréhension limitée de Lua. S’il existe un meilleur raisonnement, nous pouvons échanger des idées.

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