Ricerca…


Osservazioni

Booleans, verità e falsità sono semplici in Lua. Revisionare:

  1. Esiste un tipo booleano con esattamente due valori: true e false .
  2. In un contesto condizionale ( if , elseif , while , until ), non è richiesto un booleano. Qualsiasi espressione può essere utilizzata.
  3. In un contesto condizionale, il false e il nil falsi e tutto il resto è vero.
  4. Anche se 3 implica già questo: se provieni da altre lingue, ricorda che 0 e il conteggio delle stringhe vuoto come vero nei contesti condizionali in Lua.

Il tipo booleano

Booleans e altri valori

Quando si ha a che fare con lua è importante distinguere tra i valori booleani true e false e quelli che valutano true o false.

Ci sono solo due valori in lua che valutano in falso: nil e false , mentre tutto il resto, incluso il valore numerico 0 valutato su vero.

Alcuni esempi di cosa 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.

Operazioni logiche

Gli operatori logici in lua non restituiscono necessariamente valori booleani:

and restituirà il secondo valore se il primo valore è true;

or restituisce il secondo valore se il primo valore restituisce false;

Questo rende possibile simulare l'operatore ternario, proprio come in altre lingue:

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

Questo può anche essere usato per inizializzare le tabelle se non esistono

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

o per evitare di utilizzare le istruzioni if, rendendo il codice più facile da leggere

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)

Verifica se le variabili sono definite

Si può anche facilmente verificare se esiste una variabile (se è definita), poiché le variabili inesistenti restituiscono nil , che restituisce false.

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

L'unico caso in cui questo non si applica è quando una variabile memorizza il valore false , nel qual caso esiste tecnicamente ma continua a essere considerato falso. Per questo motivo, è un cattivo progetto creare funzioni che restituiscono false e nil seconda dello stato o dell'input. Possiamo comunque verificare se abbiamo un valore 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

Contesti condizionali

I contesti condizionali in Lua ( if , elseif , while , until ) non richiedono un valore booleano. Come molte lingue, qualsiasi valore Lua può apparire in una condizione. Le regole per la valutazione sono semplici:

  1. false e nil contano come false.

  2. Tutto il resto conta come vero.

    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
    

Operatori logici

In Lua, i booleani possono essere manipolati tramite operatori logici . Questi operatori includono not , and , and or .

Nelle espressioni semplici, i risultati sono abbastanza semplici:

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

Ordine di precedenza

L'ordine di precedenza è simile agli operatori matematici unary - , * e + :

  • not
  • allora and
  • allora or

Questo può portare a espressioni complesse:

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

Scorciatoia valutazione

Gli operatori and e or potrebbero essere valutati solo utilizzando il primo operando, a condizione che il secondo non sia necessario:

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

Operatore condizionale idiomatico

A causa della precedenza degli operatori logici, della capacità di valutazione della scorciatoia e della valutazione dei valori non false e non nil come true , un operatore condizionale idiomatico è disponibile in 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

Inoltre, a causa della natura della struttura x and a or b , a non verrà mai restituito se viene valutato come false , questo condizionale restituirà sempre b indipendentemente da cosa sia x .

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

Tabelle di verità

Gli operatori logici in Lua non "restituiscono" booleano, ma uno dei loro argomenti. Usando nil per false e numeri per true, ecco come si comportano.

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

Come puoi vedere, Lua restituirà sempre il primo valore che fa fallire o avere successo . Ecco le tabelle di verità che mostrano questo.

  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

Per chi ne ha bisogno, ecco due funzioni che rappresentano questi operatori logici.

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

Emulazione dell'operatore ternario con "e" o "operatori logici".

In lua, gli operatori logici and e or restituiscono uno degli operandi come risultato invece di un risultato booleano. Di conseguenza, questo meccanismo può essere sfruttato per emulare il comportamento dell'operatore ternario nonostante non abbia un operatore ternario "reale" nella lingua.

Sintassi

condizione e truthy_expr o falsey_expr

Utilizzare nell'assegnazione / inizializzazione variabile

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

Utilizzare nel costruttore di tabelle

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

Usa come argomento di funzione

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

Utilizzare nella dichiarazione di ritorno

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

Avvertimento

Ci sono situazioni in cui questo meccanismo non ha il comportamento desiderato. Considera questo caso

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

In un operatore ternario "reale", il valore previsto di var è false . In lua, tuttavia, la valutazione and "cade attraverso" perché il secondo operando è falso. Di conseguenza, var should not happen .

Due possibili soluzioni a questo problema, refactoring questa espressione in modo che l'operando medio non è falso. per esempio.

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

o in alternativa, usa il classico if then else costruisci.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow