2012-09-11 3 views

risposta

11

Lua fa non costanti di supporto automaticamente, ma è possibile aggiungere tale funzionalità. Ad esempio inserendo le costanti in una tabella e rendendo la tabella di sola lettura utilizzando metatable.

Ecco come fare: http://andrejs-cainikovs.blogspot.se/2009/05/lua-constants.html

La complicazione è che i nomi dei costanti non saranno solo "A" e "B", ma qualcosa come "CONSTANTS.A" e "CONSTANTS.B ". Puoi decidere di mettere tutte le tue costanti in una tabella o raggrupparle logicamente in più tabelle; ad esempio "MATH.E" e "MATH.PI" per costanti matematiche, ecc.

+2

Vedi anche http://lua-users.org/wiki/ReadOnlyTables. E si noti che è possibile impostare '_ENV' e/o' _G' su una tabella di sola lettura per simulare le costanti globali (con un certo costo in termini di prestazioni). – finnw

+0

Questa sembra una nota molto importante dal link pubblicato da @finnw: " Inoltre, questo metodo di creazione di tabelle di sola lettura ** interferisce con coppie, ipairs, next, con l'operatore # ** e con altre forme di iterazione della tabella. " – chris

2

Non esiste una parola chiave const in Lua o un costrutto simile.

La soluzione più semplice è quella di scrivere una grande cautela in un commento, dicendo che è vietato di scrivere a questa variabile ...

E 'comunque tecnicamente possibile proibire la scrittura (o lettura) ad un globale Variabile fornendo un metatable all'ambiente globale _G (o _ENV in Lua 5.2).

Qualcosa di simile a questo:

local readonly_vars = { foo=1, bar=1, baz=1 } 
setmetatable(_G, {__newindex=function(t, k, v) 
    assert(not readonly_vars[k], 'read only variable!') 
    rawset(t, k, v) 
end}) 

Poi, se si tenta di assegnare qualcosa a foo, viene generato un errore.

+0

Questo codice non è corretto. Proteggerà dall'impostazione di NUOVE variabili, ma non le modificherà. – ZzZombo

3

Come già notato non c'è const a Lua.

È possibile utilizzare questo piccolo soluzione alternativa per le variabili definite a livello globale 'proteggere' (rispetto alle tabelle protette):

local protected = {} 
function protect(key, value) 
    if _G[key] then 
     protected[key] = _G[key] 
     _G[key] = nil 
    else 
     protected[key] = value 
    end 
end 

local meta = { 
    __index = protected, 
    __newindex = function(tbl, key, value) 
     if protected[key] then 
      error("attempting to overwrite constant " .. tostring(key) .. " to " .. tostring(value), 2) 
     end 
     rawset(tbl, key, value) 
    end 
} 

setmetatable(_G, meta) 

-- sample usage 
GLOBAL_A = 10 
protect("GLOBAL_A") 

GLOBAL_A = 5 
print(GLOBAL_A)