Lua
Booleanos en Lua
Buscar..
Observaciones
Booleanos, la verdad y la falsedad son directos en Lua. Para revisar:
- Hay un tipo booleano con exactamente dos valores:
true
yfalse
. - En un contexto condicional (
if
,elseif
,while
,until
), no se requiere un valor booleano. Cualquier expresión puede ser utilizada. - En un contexto condicional,
false
ynil
cuentan como falso, y todo lo demás cuenta como verdadero. - 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:
false
ynil
cuentan como falso.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.