默认值和变量范围
default values and variable scope
我想我遗漏了一些有关变量范围和/或默认值如何工作的信息 lua。考虑以下函数:
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 版本是怎么回事?关于变量范围或导致差异的其他一些机制,我缺少什么?
在Lua中,变量是"global by default."如果没有局部(包括参数)"above"使用一个变量,它被绑定到全局环境。如果有,它绑定到上面最近的一个。
首先,你应该声明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
为 1。这是在第一次之后的每次迭代中调用的 indent
.
请注意,您的输入 table 没有子table,因此递归仅下降一级。该循环仅在初始调用中运行。这就是为什么 indentation_level
永远不会高于 1(这对您要尝试做的事情有意义)。
您可以通过 indent
local
.
来解决这个问题
我想我遗漏了一些有关变量范围和/或默认值如何工作的信息 lua。考虑以下函数:
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 版本是怎么回事?关于变量范围或导致差异的其他一些机制,我缺少什么?
在Lua中,变量是"global by default."如果没有局部(包括参数)"above"使用一个变量,它被绑定到全局环境。如果有,它绑定到上面最近的一个。
首先,你应该声明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
为 1。这是在第一次之后的每次迭代中调用的 indent
.
请注意,您的输入 table 没有子table,因此递归仅下降一级。该循环仅在初始调用中运行。这就是为什么 indentation_level
永远不会高于 1(这对您要尝试做的事情有意义)。
您可以通过 indent
local
.