Buscar..


Observaciones

Booleanos, la verdad y la falsedad son directos en Lua. Para revisar:

  1. Hay un tipo booleano con exactamente dos valores: true y false .
  2. En un contexto condicional ( if , elseif , while , until ), no se requiere un valor booleano. Cualquier expresión puede ser utilizada.
  3. En un contexto condicional, false y nil cuentan como falso, y todo lo demás cuenta como verdadero.
  4. Aunque 3 ya implica esto: si viene de otros idiomas, recuerde que 0 y la cadena vacía cuentan como verdaderos en contextos condicionales en Lua.

El tipo booleano

Booleanos y otros valores

Cuando se trata de lua, es importante diferenciar entre los valores booleanos true y false y valores que se evalúan como verdadero o falso.

Solo hay dos valores en lua que evalúan a falso: nil y false , mientras que todo lo demás, incluido el 0 numérico, se evalúa como verdadero.

Algunos ejemplos de lo que esto significa:

if 0 then print("0 is true") end --> this will print "true"
if (2 == 3) then print("true") else print("false") end --> this prints "false"
if (2 == 3) == false then print("true") end --> this prints "true"
if (2 == 3) == nil then else print("false") end
--> prints false, because even if nil and false both evaluate to false,
--> they are still different things.

Operaciones logicas

Los operadores lógicos en lua no necesariamente devuelven valores booleanos:

and devolverá el segundo valor si el primer valor se evalúa como verdadero;

or devuelve el segundo valor si el primer valor se evalúa como falso;

Esto permite simular el operador ternario, al igual que en otros idiomas:

local var = false and 20 or 30 --> returns 30
local var = true and 20 or 30 --> returns 20
-- in C: false ? 20 : 30

Esto también puede usarse para inicializar tablas si no existen

tab = tab or {} -- if tab already exists, nothing happens

o para evitar el uso de sentencias if, facilitando la lectura del código

print(debug and "there has been an error") -- prints "false" line if debug is false
debug and print("there has been an error") -- does nothing if debug is false
-- as you can see, the second way is preferable, because it does not output
-- anything if the condition is not met, but it is still possible.
-- also, note that the second expression returns false if debug is false,
-- and whatever print() returns if debug is true (in this case, print returns nil)

Comprobando si las variables están definidas

También se puede verificar fácilmente si existe una variable (si está definida), ya que las variables no existentes devuelven nil , lo que se evalúa como falso.

local tab_1, tab_2 = {}
if tab_1 then print("table 1 exists") end --> prints "table 1 exists"
if tab_2 then print("table 2 exists") end --> prints nothing

El único caso donde esto no se aplica es cuando una variable almacena el valor false , en cuyo caso técnicamente existe pero aún se evalúa como falso. Debido a esto, es un mal diseño crear funciones que devuelvan false y nil según el estado o la entrada. Sin embargo, podemos comprobar si tenemos un valor nil o false :

if nil == nil then print("A nil is present") else print("A nil is not present") end
if false == nil then print("A nil is present") else print("A nil is not present") end
-- The output of these calls are:
-- A nil is present!
-- A nil is not present

Contextos condicionales

Los contextos condicionales en Lua ( if , elseif , while , until ) no requieren un valor booleano. Como muchos idiomas, cualquier valor de Lua puede aparecer en una condición. Las reglas para la evaluación son simples:

  1. false y nil cuentan como falso.

  2. Todo lo demás cuenta como verdad.

    if 1 then
      print("Numbers work.")
    end
    if 0 then
      print("Even 0 is true")
    end
    
    if "strings work" then
      print("Strings work.")
    end
    if "" then
      print("Even the empty string is true.")
    end
    

Operadores logicos

En Lua, los booleanos pueden ser manipulados a través de operadores lógicos . Estos operadores incluyen not , and , y or .

En expresiones simples, los resultados son bastante directos:

print(not true) --> false
print(not false) --> true
print(true or false) --> true
print(false and true) --> false

Orden de precedencia

El orden de prioridad es similar a los operadores matemáticos unarios - , * y + :

  • not
  • entonces and
  • entonces or

Esto puede llevar a expresiones complejas:

print(true and false or not false and not true)
print( (true and false) or ((not false) and (not true)) )
    --> these are equivalent, and both evaluate to false

Evaluación abreviada

Los operadores and y or solamente podrían ser evaluados usando el primer operando, siempre que el segundo es innecesario:

function a()
    print("a() was called")
    return true
end

function b()
    print("b() was called")
    return false
end

print(a() or b())
    --> a() was called
    --> true
    --  nothing else
print(b() and a())
    --> b() was called
    --> false
    --  nothing else
print(a() and b())
    --> a() was called
    --> b() was called
    --> false

Operador condicional idiomático

Debido a la precedencia de los operadores lógicos, la capacidad de evaluación de atajos y la evaluación de valores no false y no nil como true , hay un operador condicional idiomático disponible en Lua:

function a()
    print("a() was called")
    return false
end
function b()
    print("b() was called")
    return true
end
function c()
    print("c() was called")
    return 7
end

print(a() and b() or c())
    --> a() was called
    --> c() was called
    --> 7
    
print(b() and c() or a())
    --> b() was called
    --> c() was called
    --> 7

Además, debido a la naturaleza de las estructuras x and a or b , a nunca se devolverá si se evalúa como false , este condicional siempre devolverá b sin importar lo que sea x .

print(true and false or 1)  -- outputs 1

Tablas de la verdad

Los operadores lógicos en Lua no "devuelven" el valor booleano, sino uno de sus argumentos. Usando nil para falso y los números para verdadero, así es como se comportan.

print(nil and nil)       -- nil
print(nil and 2)         -- nil
print(1 and nil)         -- nil
print(1 and 2)           -- 2

print(nil or nil)        -- nil
print(nil or 2)          -- 2
print(1 or nil)          -- 1
print(1 or 2)            -- 1

Como puede ver, Lua siempre devolverá el primer valor que hace que la verificación falle o tenga éxito . Aquí están las tablas de verdad que muestran eso.

  x  |  y  || and            x  |  y  || or
------------------         ------------------
false|false||  x           false|false||  y   
false|true ||  x           false|true ||  y   
true |false||  y           true |false||  x   
true |true ||  y           true |true ||  x

Para aquellos que lo necesitan, aquí hay dos funciones que representan estos operadores lógicos.

function exampleAnd(value1, value2)
  if value1 then
    return value2
  end
  return value1
end

function exampleOr(value1, value2)
  if value1 then
    return value1
  end
  return value2
end

Emulando al operador ternario con 'y' 'u' operadores lógicos.

En LUA, los operadores lógicos and y or devuelve uno de los operandos como el resultado en lugar de un resultado booleano. Como consecuencia, este mecanismo puede ser explotado para emular el comportamiento del operador ternario a pesar de que lua no tiene un operador ternario "real" en el idioma.

Sintaxis

condición y truthy_expr o falsey_expr

Uso en asignación / inicialización de variables

local drink = (fruit == "apple") and "apple juice" or "water"

Uso en constructor de tablas.

local menu =
{
  meal  = vegan and "carrot" or "steak",
  drink = vegan and "tea"    or "chicken soup"
}

Utilizar como argumento de función

print(age > 18 and "beer" or "fruit punch")

Utilizar en declaración de retorno

function get_gradestring(student)
  return student.grade > 60 and "pass" or "fail"
end

Advertencia

Hay situaciones donde este mecanismo no tiene el comportamiento deseado. Considera este caso

local var = true and false or "should not happen"

En un operador ternario 'real', el valor esperado de var es false . En lua, sin embargo, la evaluación and 'falla' porque el segundo operando es falsey. Como resultado, var should not happen lugar.

Dos posibles soluciones a este problema, refactoriza esta expresión para que el operando del medio no sea falsey. p.ej.

local var = not true and "should not happen" or false

o, alternativamente, utilizar la clásica if then else construir.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow