我们可以通过函数 debug.getlocal
来检查任意活跃函数的局部变量。该函数有两个参数,一个是要查询函数的栈层次,另一个是变量的索引。该函数返回两个值,变量名和变量的当前值。如果变量索引大于活跃变量的数量,那么函数 getlocal
返回 nil
。如果栈层次无效,则会抛出异常(我们可以使用函数 debug.getinfo
来检查栈层次是否有效)。
Lua
语言按局部变量在函数中的出现顺序对他们进行编号,但编号只限于在函数当前作用域中活跃的变量。例如,考虑如下的代码:
function foo(a, b) local x do local c = a - b end local a = 1 while true do local name, value = debug.getlocal(1, a) if not name then break end print(name, value) a = a + 1 end end
调用 foo(10, 20)
会输出
a 10 b 20 x nil a 4
索引为 1
的变量是 a
(第一个参数),索引为 2
的变量是 b
,索引为 3
的变量是 x
,索引为 4
的变量是内存的 a
。在 getlocal
被调用的时候, c
已经离开了作用域,而 name
和 value
还未出现于作用域。
注意
局部变量只在初始化后才可见。
从 Lua5.2
开始,值为负数的索引获取可变长参数函数的额外参数,索引 -1
指向第一个额外参数。此时,变量的名称永远是 "(*vararg)"
。
我们还可以通过函数 debug.setlocal
改变局部变量的值,该函数的前两个参数与 getlocal
相同,分别是栈层次和变量索引,而第三个参数是该局部变量的新值。该函数的返回值是变量名,如果变量索引超出了范围则返回 nil
。