Lua中是否有类似于const或其他任何关键字可以执行相同的任务?

48

Lua中是否有const关键字?或者其他类似的东西?因为我想将我的变量定义为const并防止变量值的更改。 提前感谢。

4个回答

52

我知道这个问题已经七年了,但是Lua 5.4终于为开发者带来了const

local a <const> = 42
a = 100500

会产生一个错误:

lua: tmp.lua:2: attempt to assign to const variable 'a'

文档: https://www.lua.org/manual/5.4/manual.html#3.3.7


5
重要提示:错误将在“编译”时产生(当代码被加载和评估时),而不是在运行时! - BotOfWar

24

更新:2023年11月

继2020年6月发布Lua 5.4之后,我们增加了对常量变量的支持。有关更多信息,请参考Ainar-G的回答(链接)


原始答案

Lua不会自动支持常量,但你可以添加这个功能。例如,将常量放入一个表中,并使用元表将表设置为只读。

以下是如何实现的:http://andrejs-cainikovs.blogspot.se/2009/05/lua-constants.html

复杂之处在于,你的常量名称不仅仅是"A"和"B",而是类似于"CONSTANTS.A"和"CONSTANTS.B"。你可以决定将所有常量放入一个表中,或者根据逻辑将它们分组到多个表中;例如,数学常量可以放在"MATH.E"和"MATH.PI"中。


5
请参见 http://lua-users.org/wiki/ReadOnlyTables。请注意,您可以将 _ENV 和/或 _G 设置为只读表以模拟全局常量(但会影响性能)。 - finnw
2
这似乎是@finnw发布的链接中非常重要的一条注释:“此外,创建只读表的方法会干扰对成对、ipairs、next、#运算符和其他形式的表迭代的使用。” - chris

5

如前所述,Lua 中没有 const

您可以使用以下小技巧来“保护”全局定义的变量(与受保护的表相比):

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)

2

在Lua中没有像const这样的关键字或类似的结构。

最简单的解决方法是在注释中写一个大的警告,告诉用户禁止写入此变量...

然而,通过为全局环境_G(或在Lua 5.2中的_ENV)提供元表,可以在技术上禁止对全局变量进行写入(或读取)。

类似于以下内容:

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

如果你试图对foo进行赋值操作,会抛出一个错误。


这段代码是不正确的。它可以防止设置新变量,但无法防止更改现有变量。 - ZzZombo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接