【问题标题】:How to declare a variable without initting it to nil in Lua?如何在 Lua 中声明一个变量而不将其初始化为零?
【发布时间】:2013-03-14 15:47:56
【问题描述】:

我发现执行以下操作非常有用:

if not variable then
    variable = value
end

当然,我通常宁愿那个变量是本地的,但我不能在我的 if 中声明它是本地的,否则它将无法访问。

所以有时我会这样做:

local variable
if not variable then
    variable = value
end

问题是,当我遍历这段代码时,变量声明将变量设置为 nil。如果我可以接受一个全局值(我可以),我可以通过不在 if 块之外声明变量来绕过它。

但是有没有什么方法可以让我既拥有我的本地价值又让它保持它的价值?

【问题讨论】:

  • 不清楚您在这里要做什么。如果您创建一个新的局部变量,那么根据定义它的值将为零。那么您到底要检查哪个变量的值?是否要声明一个新变量?
  • 是递归函数调用吗?

标签: variables lua scope local declaration


【解决方案1】:

首先,or 在 Lua 中的定义方式为您提供了一个很好的习惯用法,可以完全避免使用 if

variable = variable or value

如果变量是nilor 将计算其第二个操作数。当然,这只有在false 不是variable 的有效值时才有效(因为就or 而言,falsenil 都是“假”)。

但是,您仍然存在需要在某处声明变量的问题。我想你的问题是,在全局循环的情况下,你认为你必须这样做:

while condition do
    variable = variable or value
    process(variable)
end

(这将使variable 成为全局)或

while condition do
    local variable
    variable = variable or value
    process(variable)
end

这是没有意义的,因为local 将范围限制为一次迭代并将variable 重新初始化为`nil。

可以做的就是创建另一个块来限制local 变量的范围,但什么也不做:

do
    local variable
    while condition do
        variable = variable or value
        process(variable)
    end
end

【讨论】:

  • 感谢您的回答。实际上,我想知道,因为我想测试“本地将范围限制为一次迭代”是否正确。
  • Perl 和 Ruby 都有一个相似的习惯用法,使用 '||'或运算符,因此您会看到诸如 val||='default'; 之类的代码这个值或默认习惯用法非常有用。
  • @ChuckCottrill 是的,你可以在 JavaScript 中做同样的事情。可能在大多数具有“真”和“假”概念的语言中。
【解决方案2】:

有一种简单的方法可以测试循环内局部变量的范围:

local a = "this is external a"
for x = 1, 3 do
    print(a)
    local a = "THIS IS INTERNAL a"
    print(a)
end

如果你运行它,你会得到:

this is external a
THIS IS INTERNAL a
this is external a
THIS IS INTERNAL a
this is external a
THIS IS INTERNAL a

如果循环内的本地 a 存活到下一次迭代,那么在第一次打印后它应该只打印“这是内部 a”,因为内部 a 会遮蔽外部a。两个字符串交替意味着内部本地 a 永远不会在循环底部存活。

当然,即使它确实存在,您也会遇到内部本地声明的问题,即每次通过循环时都会影响上一次迭代的本地 a。本质上,您将无法访问上一次迭代的 a 版本,并且到第三次迭代时,您将拥有 3 个单独的内部本地变量,只有最后一个可以访问。就像您这样做一样:

local a = "THIS IS INTERNAL a"
local a = "THIS IS INTERNAL a"
local a = "THIS IS INTERNAL a"

【讨论】:

    猜你喜欢
    • 2020-05-09
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2013-04-08
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多