雖然 Lua 是一門解釋型語言,但其源碼在執行前總會被編譯為中間字節碼。這一過程對開發者大多數時候是透明的,但理解它有助於掌握 Lua 的運行原理。
dofile 用於載入並立即執行一個 Lua 文件。相對應地,loadfile 僅載入並編譯文件,返回一個編譯後的 chunk(作為一個函數),而不自動執行:
c = loadfile('./test.lua')
c() -- 執行編譯後的 chunk
dofile 的行為等價於:
function dofile(filename)
local f = assert(loadfile(filename))
return f()
end
類似地,load 函數接受字符串作為參數,編譯並返回 chunk:
f = load('i = i + 1')
i = 0
f(); print(i) --> 1
f(); print(i) --> 2
也可以使用 luac 命令直接將 Lua 文件編譯為二進制字節碼文件:
luac -o prog.lc prog.lua
lua prog.lc
Lua 在遇到無法接受的情況時會拋出錯誤。開發者也可以通過 error 函數顯式拋出錯誤:
print('enter a number:')
n = io.read('*n')
if not n then error('invalid input') end
assert 函數檢查第一個參數,若為 false 則拋出錯誤,第二個參數為可選的錯誤信息:
n = io.read()
assert(tonumber(n), 'invalid input: ' .. n .. ' is not a number')
pcall 以保護模式調用函數,捕獲運行時錯誤:
local ok, msg = pcall(function()
assert(false)
end)
print(ok, msg) -- false, 錯誤信息
錯誤信息不一定是字符串,可以是表等任意類型:
local ok, err = pcall(function()
error({code = 502})
end)
print(err.code) -- 502
error 的第二個參數 level 指定錯誤報告的位置:1 為 error 的調用者,2 為調用者的調用者,以此類推。這對於庫函數報告調用者的錯誤位置非常有用。
若需要完整的調用堆棧,可使用 xpcall,它接受一個錯誤處理函數作為參數,在錯誤發生時調用,從而獲取完整堆棧信息。