2012-09-11 11 views

Respuesta

11

Lua hace no constantes de soporte de forma automática, pero puede agregar esa funcionalidad. Por ejemplo, colocando sus constantes en una tabla y haciendo que la tabla sea de solo lectura usando metatabla.

Aquí es cómo hacerlo: http://andrejs-cainikovs.blogspot.se/2009/05/lua-constants.html

La complicación es que los nombres de sus constantes no serán simplemente "A" y "B", sino algo así como "CONSTANTS.A" y "CONSTANTS.B ". Puede decidir poner todas sus constantes en una tabla, o agruparlas lógicamente en varias tablas; por ejemplo "MATH.E" y "MATH.PI" para constantes matemáticas, etc.

+2

Ver también http://lua-users.org/wiki/ReadOnlyTables. Y tenga en cuenta que puede establecer '_ENV' y/o' _G' en una tabla de solo lectura para simular constantes globales (con algún costo de rendimiento). – finnw

+0

Esto parece una nota muy importante del enlace publicado por @finnw: " Además, este método de creación de tablas de solo lectura ** interfiere con los pares, las ipairs, el siguiente, el operador # y otras formas de iteración de tablas. – chris

2

No existe la palabra clave const en Lua o construcción similar.

La solución más fácil es escribir un gran precaución en un comentario, diciendo que está prohibido escribir en esta variable ...

Sin embargo, es técnicamente posible para prohibir la escritura (o lectura) a un mundial variable proporcionando un metatable al entorno global _G (o _ENV en Lua 5.2).

Algo como esto:

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}) 

Entonces, si intenta asignar algo a foo, se genera un error.

+0

Este código es incorrecto. Protegerá contra el establecimiento de variables NUEVAS, pero no las cambiará. – ZzZombo

3

Como ya se indicó, no hay const en Lua.

Se puede utilizar esta solución poco a variables definidas a nivel mundial 'proteger' (en comparación con las tablas protegidas):

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) 
Cuestiones relacionadas