我认为我遗漏了关于变量范围和/或默认值如何工作的问题。考虑以下功能:
function printtable(x, indentation_level)
indentation_level = indentation_level or 0
function indent()
dent = ''
for i=1,indentation_level do
dent = dent..'__'
end
return dent
end
if type(x) ~= 'table' then
return tostring(x)
end
rpr = ''
for k, v in pairs(x) do
rpr = rpr..indent()..'['..printtable(k)..']'..' = '..printtable(v, indentation_level+1)
end
return rpr
end
当我用
调用它时t = {1,2,3}
print(printtable(t))
我会得到[1] = 1__[2] = 2__[3] = 3
我的期望是[1] = 1[2] = 2[3] = 3
我在python中重写了这个函数,看看我的逻辑错误在哪里:
def printdict(x, indentation_level=0):
def indent():
dent = ''
for i in range(indentation_level):
dent += '__'
return dent
if type(x) != dict:
return str(x)
rpr = ''
for k, v in x.items():
rpr = rpr+indent()+'['+printdict(k)+'] = '+printdict(v, indentation_level+1)
return rpr
当我用:
调用它时t = {1:1,2:2,3:3}
print(printdict(t))
我得到了我期望的结果:[1] = 1[2] = 2[3] = 3
那么,lua版本发生了什么?我对变量范围或其他一些导致差异的机制缺少什么?
答案 0 :(得分:1)
首先,您应该声明indent
,dent
,rpr
,可能printtable
为local
。 (与Python不同,Lua要求我们声明我们的变量来指定它们的范围。参数和循环变量自动是定义它们的块的本地变量。)
问题是indent
是全球性的。
请注意,indentation_level
是printtable
的本地,因为它是一个参数。 indent
引用了indentation_level
,这意味着indent
是关闭。闭包是一个存储对外部局部变量的引用的函数。
每当您致电printtable
时,它都会定义indent
的新版本,其中indentation_level
的范围在当时。在您的代码中,indent
是一个全局变量,因此indent
的每个新定义都会覆盖前一个定义。
在这个循环中:
for k, v in pairs(x) do
rpr = rpr..indent()..'['..printtable(k)..']'..' = '..printtable(v, indentation_level+1)
end
...您调用printtable
,indent
定义indentation_level
,indent
为1.这是indentation_level
,在第一次迭代后的每次迭代都会被调用。 / p>
请注意,您的输入表没有子表,因此递归只会降低一个级别。该循环仅在初始调用中运行。这就是为什么indent
永远不会高于1(这对你要做的事情有意义)。
您可以通过制作local
{{1}}来解决此问题。
答案 1 :(得分:0)
在Lua中,变量“默认为全局”。如果没有本地(包括参数)“上面”使用变量,则它将绑定到全局环境。如果有的话,它会绑定到上面最近的一个。