00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Operatori

Gli operatori sono i mattoni fondamentali per costruire espressioni in qualsiasi linguaggio di programmazione. Lua offre un insieme completo di operatori aritmetici, relazionali, logici e di altro tipo. In questo articolo li analizzeremo tutti nel dettaglio, con esempi pratici e gli idiomi piu comuni.

Operatori Aritmetici

Lua supporta tutti gli operatori aritmetici standard, inclusa la divisione intera introdotta in Lua 5.3:

Operatore Descrizione Esempio Risultato
+ Addizione 10 + 3 13
- Sottrazione 10 - 3 7
* Moltiplicazione 10 * 3 30
/ Divisione (float) 10 / 3 3.3333
// Divisione intera 10 // 3 3
% Modulo (resto) 10 % 3 1
^ Esponenziazione 2 ^ 10 1024.0
- Negazione unaria -42 -42

Vediamo gli operatori in azione:

local a, b = 17, 5

-- Operazioni di base
print("Addizione:      " .. a + b)      --> 22
print("Sottrazione:    " .. a - b)      --> 12
print("Moltiplicazione:" .. a * b)      --> 85

-- Divisione float vs divisione intera
print("Divisione /     " .. a / b)      --> 3.4
print("Divisione //    " .. a // b)     --> 3

-- Modulo
print("Modulo:         " .. a % b)      --> 2

-- Esponenziazione (restituisce sempre float)
print("Potenza:        " .. 2 ^ 8)     --> 256.0

-- Negazione unaria
local x = 10
print("Negazione:      " .. -x)        --> -10

Divisione Intera e Modulo

La divisione intera // arrotonda sempre verso il basso (verso meno infinito), e il modulo segue la stessa convenzione:

-- Divisione intera con numeri negativi
print(7 // 2)           --> 3
print(-7 // 2)          --> -4  (arrotonda verso -infinito)
print(7 // -2)          --> -4

-- Il modulo rispetta l'identita: a % b == a - (a // b) * b
print(7 % 3)            --> 1
print(-7 % 3)           --> 2   (sempre non-negativo con divisore positivo)

-- Uso pratico: verificare se un numero e pari
local numero = 42
if numero % 2 == 0 then
    print(numero .. " e pari")          --> 42 e pari
end

Esponenziazione

L’operatore ^ restituisce sempre un valore float, anche con operandi interi:

print(2 ^ 10)               --> 1024.0 (float, non integer)
print(type(2 ^ 10))         --> number
print(math.type(2 ^ 10))    --> float

-- Radice quadrata tramite esponenziazione
print(25 ^ 0.5)             --> 5.0
print(27 ^ (1/3))           --> 3.0 (radice cubica)

Operatori Relazionali

Gli operatori relazionali confrontano due valori e restituiscono un booleano (true o false):

Operatore Descrizione Esempio Risultato
== Uguale a 5 == 5 true
~= Diverso da 5 ~= 3 true
< Minore di 3 < 5 true
> Maggiore di 5 > 3 true
<= Minore o uguale 5 <= 5 true
>= Maggiore o uguale 5 >= 3 true

Nota importante: in Lua l’operatore di disuguaglianza e ~=, non != come in C, Java o Python.

local a, b = 10, 20

print(a == b)       --> false
print(a ~= b)       --> true
print(a < b)        --> true
print(a > b)        --> false
print(a <= 10)      --> true
print(a >= 20)      --> false

-- Confronto tra stringhe (ordine lessicografico)
print("abc" < "abd")        --> true
print("abc" < "ab")         --> false
print("abc" == "abc")       --> true

-- Le tabelle vengono confrontate per riferimento, non per contenuto
local t1 = {1, 2, 3}
local t2 = {1, 2, 3}
local t3 = t1

print(t1 == t2)     --> false (oggetti diversi in memoria)
print(t1 == t3)     --> true  (stesso riferimento)

Operatori Logici

Lua dispone di tre operatori logici: and, or e not. La loro particolarita e che and e or restituiscono uno degli operandi, non necessariamente un booleano:

Operatore Descrizione Comportamento
and E logico Restituisce il primo operando falso, o l’ultimo
or O logico Restituisce il primo operando vero, o l’ultimo
not Negazione Restituisce true o false
-- Comportamento di "and"
print(true and "ciao")      --> ciao   (primo e vero, restituisce il secondo)
print(false and "ciao")     --> false  (primo e falso, restituisce il primo)
print(nil and "ciao")       --> nil    (nil e falso)
print("a" and "b")          --> b      (entrambi veri, restituisce il secondo)

-- Comportamento di "or"
print(true or "ciao")       --> true   (primo e vero, restituisce il primo)
print(false or "ciao")      --> ciao   (primo e falso, restituisce il secondo)
print(nil or "default")     --> default
print("a" or "b")           --> a      (primo e vero, restituisce il primo)

-- Comportamento di "not"
print(not true)             --> false
print(not false)            --> true
print(not nil)              --> true
print(not "ciao")           --> false  (le stringhe sono truthy)
print(not 0)                --> false  (0 e truthy in Lua!)

Cortocircuito (Short-Circuit Evaluation)

Gli operatori and e or usano la valutazione a cortocircuito: se il risultato e determinato dal primo operando, il secondo non viene valutato:

-- La funzione costosa() non viene mai chiamata
local risultato = false and costosa()   -- restituisce false
local risultato = true or costosa()     -- restituisce true

Idioma: Valore di Default con “or”

Uno degli idiomi piu usati in Lua sfrutta or per assegnare valori di default:

-- Se "nome" e nil o false, usa "Sconosciuto"
local nome = nil
local nome_visualizzato = nome or "Sconosciuto"
print(nome_visualizzato)    --> Sconosciuto

-- Funzione con parametro opzionale
local function saluta(nome)
    nome = nome or "Mondo"
    print("Ciao, " .. nome .. "!")
end

saluta("Lua")       --> Ciao, Lua!
saluta()            --> Ciao, Mondo!

Attenzione: questo idioma non funziona se false e un valore valido:

-- Problema: false viene trattato come "assente"
local attivo = false
local valore = attivo or true   -- restituisce true, non false!

Idioma: Operatore Ternario Simulato

Lua non ha un operatore ternario (? : come in C), ma lo si puo simulare con and/or:

-- Equivalente di: risultato = condizione ? valore_vero : valore_falso
local x = 10
local segno = (x > 0) and "positivo" or "non positivo"
print(segno)                --> positivo

-- Altro esempio
local eta = 20
local categoria = (eta >= 18) and "adulto" or "minorenne"
print(categoria)            --> adulto

Operatore di Concatenazione (…)

L’operatore .. concatena due stringhe. Se un operando e un numero, viene automaticamente convertito in stringa:

local nome = "Lua"
local versione = 5.4

local messaggio = "Benvenuto in " .. nome .. " " .. versione .. "!"
print(messaggio)            --> Benvenuto in Lua 5.4!

-- Concatenazione ripetuta (usa table.concat per efficienza)
local parti = {}
for i = 1, 5 do
    parti[i] = "parte" .. i
end
local risultato = table.concat(parti, ", ")
print(risultato)            --> parte1, parte2, parte3, parte4, parte5

Per concatenazioni ripetute in un ciclo, e piu efficiente raccogliere le parti in una tabella e usare table.concat().

Operatore di Lunghezza (#)

L’operatore # restituisce la lunghezza di una stringa (in byte) o di una sequenza in una tabella:

-- Lunghezza delle stringhe
local s = "Ciao Mondo"
print(#s)                   --> 10

-- Lunghezza delle sequenze (tabelle con indici numerici consecutivi da 1)
local lista = {"a", "b", "c", "d"}
print(#lista)               --> 4

-- Attenzione: con tabelle che hanno "buchi", il comportamento e indefinito
local t = {1, nil, 3}
print(#t)                   -- risultato imprevedibile (potrebbe essere 1 o 3)

-- Uso pratico: aggiungere un elemento alla fine di una tabella
local numeri = {10, 20, 30}
numeri[#numeri + 1] = 40
print(numeri[4])            --> 40

Precedenza degli Operatori

La tabella seguente elenca gli operatori dalla precedenza piu alta alla piu bassa:

1.  ^                      (esponenziazione, associativo a destra)
2.  not  #  -              (operatori unari)
3.  *   /   //   %         (moltiplicazione e divisione)
4.  +   -                  (addizione e sottrazione)
5.  ..                     (concatenazione, associativo a destra)
6.  <   >   <=  >=  ~=  == (comparazione)
7.  and                    (e logico)
8.  or                     (o logico)

In caso di dubbio, usa le parentesi per rendere esplicita la precedenza:

-- Senza parentesi
local r = 2 + 3 * 4            -- 14 (la moltiplicazione ha precedenza)

-- Con parentesi per chiarezza
local r = 2 + (3 * 4)          -- 14, piu chiaro
local r = (2 + 3) * 4          -- 20, comportamento diverso

-- L'esponenziazione e associativa a destra
print(2 ^ 2 ^ 3)               --> 256 (equivale a 2 ^ (2 ^ 3) = 2 ^ 8)

-- La concatenazione e associativa a destra
local s = "a" .. "b" .. "c"    -- equivale a "a" .. ("b" .. "c")

Riepilogo Pratico

Ecco un esempio completo che utilizza diversi operatori:

-- Calcolo del prezzo finale con sconto
local function calcola_prezzo(prezzo_base, sconto_percentuale, tasse)
    sconto_percentuale = sconto_percentuale or 0
    tasse = tasse or 22

    local sconto = prezzo_base * sconto_percentuale / 100
    local prezzo_scontato = prezzo_base - sconto
    local importo_tasse = prezzo_scontato * tasse / 100
    local prezzo_finale = prezzo_scontato + importo_tasse

    return prezzo_finale
end

local prezzo = calcola_prezzo(100, 15)
print("Prezzo finale: " .. string.format("%.2f", prezzo) .. " EUR")
--> Prezzo finale: 103.70 EUR

Conclusione

Gli operatori di Lua coprono tutte le necessita della programmazione quotidiana. La particolarita piu importante da ricordare e il comportamento degli operatori logici and e or, che restituiscono gli operandi stessi anziche un semplice booleano. Questo permette di scrivere codice conciso e idiomatico, come il pattern a = a or valore_default, che e onnipresente nel codice Lua di qualita.