Lua极简入门指南(三): loadfile和错误处理
编译
Lua虽然是解释性语言,但Lua源码总是被编译为中间形式后再执行。
dofile用于载入并执行一个Lua文件,相比之下,loadfile用于载入一个Lua文件,但并不执行,确切的说loadfile编译了一个chunk,并返回此被编译的chunk(被作为一个函数):
c=loadfile('./test.lua') c()
dofile可以被实现为:
functiondofile(filename) localf=assert(loadfile(filename)) returnf() end
一个类似loadfile的函数load,它使用字符串(而非文件)作为参数,返回被编译的chunk:
f=load('i=i+1') i=0 f();print(i) -->1 f();print(i) -->2
另外,我们可以使用命令luac来直接编译Lua文件:
luac-oprog.lcprog.lua luaprog.lc
错误
Lua遇见任何不可接受的条件时会产生错误。例如:
localt={} --出错 t=t+1
我们可以显式的调用error函数来产生一个错误,error接受一个错误消息作为参数:
print'enteranumber:' n=io.read('*n') ifnotnthenerror('invalidinput')end
assert函数也可以产生错误。assert函数检查第一个参数是否为false,如果不为false就返回此参数,如果为false就产生一个错误。assert的第二个参数,错误消息,是可选的。范例:
n=io.read() assert(tonumber(n),'invalidinput:'..n..'isnotanumber')
pcall函数可以捕获错误:
localok,msg=pcall(function() assert(false) end) print(ok,msg)
pcall函数使用保护模式(protectedmode)调用第一个参数(此参数为一个函数),如果被调用的函数执行不存在错误,pcall返回true并返回被调用函数的所有返回值,如果被调用的函数产生了错误,pcall返回false并附带上错误消息。严格来说,错误消息不一定需要是字符串:
localok,err=pcall(function() error({code=502}) end) print(err.code)
追踪错误
我们先看一个函数:
functionfoo(str) iftype(str)~='string'then error('stringexpected') end --... end foo(1)
foo函数需要一个字符串参数,我们执行上面的代码:
lua:test.lua:3:stringexpected
输出指出了错误出现在foo函数中(因为foo函数调用了error),而实际上,错误是foo的调用者产生的,而非foo产生的。我们可以设置level来修正这个报错:
functionfoo(str) iftype(str)~='string'then error('stringexpected',2) end --... end
error函数的第二个参数为level,用于指定报错的位置,level值为1表示error的调用者,值为2表示error的调用者的调用者,以此类推。
pcall只能返回错误消息,很多时候我们需要完整的调用栈,这时可以使用xpcall函数。xpcall函数可以接收一个消息handler作为参数,在被调用函数出现错误时,消息handler会被调用,通过其就可以获取到当前调用栈的信息。