尝试比较 nil 和数字导致堆栈回溯?

我正在按照此链接操作 Lua: https://www.lua.org/pil/4.2.html,并且对某个点感到困惑。

Lua 5.2.4  版权所有 (C) 1994-2015 Lua.org,PUC-Rio
> x=10
> local i=1
> while i<=x do
>>  local x = i*2
>>  print(x)
>>  i=i+1
>> end
stdin:1: 尝试比较 nil 和数字
堆栈追踪:
    stdin:1: 在主块中
    [C]: 在 ?

我猜想这个错误信息表明 while i<=x 表达式有问题。非常感谢您提供任何意见。 编辑: 我刚刚意识到可能是因为它在终端中无法工作。

点赞
用户11144794
用户11144794

在交互终端中它并没有起作用。因为一旦你按回车键,“local i=1”被终端理解为一个单独的代码块。这就是为什么会出现“尝试将nil与数字进行比较”的错误,因为在这种情况下i没有被定义,即为nil。为了修正这个错误,把前两行和while循环放在do代码块里,如下所示。

> do
>>  x=10
>>  local i=1
>>  while i<=x do
>>    local x=i*2 
>>    print(x)
>>    i=i+1
>>  end
>> end
2
4
6
8
10
12
14
16
18
20
>

2019-11-06 08:50:32
用户3371355
用户3371355

实际上问题出在 local i=1

> local i = 1
> print(i)

问题在于当运行控制台时,该行似乎是一个块,变量是该块内部的局部变量。 您可以通过使用全局变量来修复它,或者您可以这样做

> local i = 1 do
>> print(i)
>> end

这将导致块结构如下[local i [print(i)]],因此可以访问 i。 还要注意,local x = i*2 是有效的,因为它在 while - do 块内。

如果您的代码在 Lua 文件内,则还可以正确工作。

2019-11-06 08:51:23
用户2932052
用户2932052

我在Lua 5.3.4中也能重现这个问题。

如果你继续阅读Lua文档,4.2章——局部变量和块,你会看到这句话:

注意,在交互模式下输入这个例子时,它将不能按预期工作。第二行,local i = 1,本身就是一个完整的代码块。

这正是问题的关键。因此,Lua解释器似乎对最外层块的支持有限(它在Lua文件中明确存在)。但考虑到语言和解释器的紧凑性,这种行为对我来说是可以接受和理解的。

因此,在交互模式下,

要么省略变量i之前的local以使它正常工作:

Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>x=10
Lua>i=1
Lua>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end

要么将整个代码块用一个块括起来:

Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>do
...>local x=10
...>local i=1
...>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end
...>end

这两种选择都会产生正常(和预期)的输出:

2
4
6
8
10
12
14
16
18
20
2019-11-06 08:59:46