Operación ternaria

Los veteranos familiarizados con C/C++ conocen el operador ternario a ? b : c. Esta escritura, al reemplazar sentencias simples de condición, puede mantener el código lo más conciso posible sin aumentar la dificultad de lectura.

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

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

Operación ternaria en Lua

La semántica nativa de Lua no implementa el operador ternario; generalmente se simula mediante los operadores lógicos and y or.

En Lua, tanto and como or utilizan la "evaluación de cortocircuito (short_cur evaluation)", es decir, solo evalúan el segundo operando cuando es necesario. (Programación en Lua)

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

Enumerando todas las posibilidades:

Cuando a > b:

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

Cuando a <= b:

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

¡Perfecto!

Trampa del operador ternario en Lua

Siguiendo el principio de lo particular a lo general:

  • La forma general del operador ternario a ? b : c

    a = true, el resultado es b
    a = false, el resultado es c

  • Corresponde a 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

Se puede ver que cuando b = false, el a and b or c simulado en Lua siempre devuelve c, por lo que no puede reproducir el comportamiento original del operador ternario.

Programación en Lua también recomienda usar if-else para evitar esta situación.

Generalización de a and b or c

Entonces, ¿hay alguna manera de resolver el problema de que b = false falle?

Esto me recuerda que en C hay una pregunta de examen habitual: escribe un método usando una definición de macro que devuelva el menor de dos valores.

Cuando vi este problema por primera vez en la escuela, mi primera reacción fue la siguiente:

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

Sin embargo, esta escritura no devuelve el resultado correcto en muchos entornos de uso anidados. Por ejemplo: 2 * MIN(3, 4) se expande a 2 * 3 < 4 ? 3 : 4 = 6 < 4 ? 3 : 4, y el resultado es 4.
Una forma más "de ingeniero" es:

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

Los estudiantes curiosos pueden consultar: La forma correcta de escribir definiciones de macro, definición de macro del operador ternario

A partir de este ejemplo, me pregunté cómo se puede garantizar que en a and b or c, b sea verdadero o que b no genere ambigüedad.

  • La precedencia de and es mayor que la de or; simplemente cambiar el orden de las operaciones no sirve.
  • Entonces pensé en el todopoderoso table de Lua. ¿Podemos poner a, b y c en tablas para cambiar la existencia de b? Ten en cuenta que {nil} también es un objeto true.
    Reemplazamos a, b y c por tablas: {a} and {b} or {c}.
  • En el operador ternario, a es la condición y el resultado es b o c. En realidad, a no necesita ponerse en una tabla; de lo contrario, {a} siempre sería true y perdería el sentido de condición. Y {b} or
    {c} también es necesariamente una tabla, y esa tabla tiene un solo elemento. Entonces se puede acceder a él mediante
  • En resumen, la forma más general del operador ternario en Lua es: (a and {b} or {c})

Resumen

Ciertamente, para saber la forma del operador ternario en Lua, basta con buscar para encontrar la respuesta deseada. El proceso de razonamiento anterior tiene algo de sospecha de saber la respuesta de antemano y acercarse deliberadamente a ella. Sin embargo, creo firmemente que al demostrar un problema, la conclusión no es lo más importante; lo importante es el proceso de argumentación. Este artículo solo intenta reconstruir el proceso de derivación del operador ternario generalizado en Lua basándose en mi comprensión superficial de Lua. Si hay un mejor proceso de razonamiento, podemos intercambiar ideas.

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