esg*_*dir 3 variables recursion lua scripting-language
我对lua很新,我想了解以下行为.
当我尝试运行以下递归函数时:
local func = function ( n )
if n == 1 then return 1
else return n * func( n - 1 )
end
end
print( func( 5 ) )
Run Code Online (Sandbox Code Playgroud)
程序将失败并出现错误:
lua: main.lua:16: attempt to call a nil value (global 'func')
stack traceback:
main.lua:16: in local 'func'
main.lua:38: in main chunk
[C]: in ?
Run Code Online (Sandbox Code Playgroud)
这是好的,因为根据解释,func变量的本地版本尚不知道,所以它试图调用全局版本.但是当我删除本地关键字时,以下代码正常工作?
func = function ( n )
if n == 1 then return 1
else return n * func( n - 1 )
end
end
print( func( 5 ) )
Run Code Online (Sandbox Code Playgroud)
程序打印120作为结果,但全局func从未初始化或之前使用过.怎么可能,这也不会引发错误?引用全局func的第二个例子不是第一个例子吗?
引用全局func的第二个例子不是第一个例子吗?
它是 :)
你看,编译新函数时是否存在值无关紧要.它不检查存储在func变量中的值,而是每次调用时都会查找它.唯一重要的是变量的可见性.如果变量在本地范围内不可见,则它被视为全局变量,并将在全局环境表中查找.有关详细信息,请参阅Lua手册,第3.5章- 可见性规则
第一个示例不起作用,因为local func在计算完整表达式之前变量不可见.这就是为什么第一个例子中断,试图调用缺少的全局变量.
如果您希望该func是本地的,请声明该变量,然后分配它.喜欢:
local func
func = function ( n )
if n == 1 then return 1
else return n * func( n - 1 )
end
end
print( func( 5 ) )
Run Code Online (Sandbox Code Playgroud)
在这种情况下,使用Lua的语法糖可能会更容易:
local function func( n )
if n == 1 then return 1
else return n * func( n - 1 )
end
end
print( func( 5 ) )
Run Code Online (Sandbox Code Playgroud)
它将被精确翻译为相同的声明变量序列,然后分配它.
这次func变量对于new是可见的function(n),因此它将读取从该特定upvalue调用的值.
请注意,通过func稍后将不同的内容分配给变量,仍然可以"中断"该功能.Lua中的函数(与任何其他值一样)没有名称,只有变量.因此,对函数的调用不是硬编译的,调用的函数值总是在每次调用之前从变量中获取.