Lua 易错点
任何字符串进行数学运算时, 会自动向数字转换, 但是如果不能转换则会使程序默默退出.
任何不同类型的比较, 都是 false, 如 3 ~= "3".
for exp1, exp2, exp3 do <执行体> end 中, 三个表达式都是一次性求值.
for 中的控制变量会被自动声明为局部变量, 并且仅在循环体内可见.
i = 5 --> 全局 i. -- ..... for i=1, 3, 1 do end --> 这里的 i 是局部变量, 不是全局 i. print(i) --> 这里是全局 i, 没有改变, 依然是 5.
函数可以返回多个值, 只有函数作为表达式的最后一个值, 才能保留全部的返回值. 如下:
function foo0() end function foo1() return 1 end function foo2() return 1, 2 end table x = {foo2(), 0} --> t[1] = 1, t[2] = 0. 这里发生了截断 table y = {0, foo0(), foo2()} --> t[1] = 0, t[2] = nil, t[3] = 1, t[4] = 2.
return (foo2()) 外层的大括号会使 foo2 的返回值只能保留第一个.
定义递归函数, 需要先声明, 后定义, 一定要分开写. 详见 <Lua 程序设计> 中文第二版 p51.
正确:
fun = function (arg) print('This is global function') end
local fun -- 这里很重要, 一定要先声明, 在定义. fun = function (arg) if arg > 0 then fun(arg-1) print('This is local function') end end -- Right. fun(2) -- [[ This is local function This is local function ]]
错误:
fun = function (arg) print('This is global function') end local fun = function (arg) if arg > 0 then fun(arg-1) print('This is local function') end end -- Wrong! 这里首先执行了 global fun, 第二次才执行了 local fun. fun(2) --[[ This is global function This is local function ]]
loadstring 所加载的程序块是在全局作用于下执行的, 因此任何 local 变量都不能被 loadstring 的程序块所见:
i = 123 -- loadstring 可见. local i = 'abc' bar = loadstring('print(i)') -- 只能看见全局 i. loadstring 在编译时不涉及词法域. bar() -- 123