Lua極簡(jiǎn)入門指南(三): loadfile和錯(cuò)誤處理
編譯
Lua 雖然是解釋性語(yǔ)言,但 Lua 源碼總是被編譯為中間形式后再執(zhí)行。
dofile 用于載入并執(zhí)行一個(gè) Lua 文件,相比之下,loadfile 用于載入一個(gè) Lua 文件,但并不執(zhí)行,確切的說(shuō) loadfile 編譯了一個(gè) chunk,并返回此被編譯的 chunk(被作為一個(gè)函數(shù)):
c = loadfile('./test.lua')
c()
dofile 可以被實(shí)現(xiàn)為:
function dofile(filename)
local f = assert(loadfile(filename))
return f()
end
一個(gè)類似 loadfile 的函數(shù) load,它使用字符串(而非文件)作為參數(shù),返回被編譯的 chunk:
f = load('i = i + 1')
i = 0
f(); print(i) --> 1
f(); print(i) --> 2
另外,我們可以使用命令 luac 來(lái)直接編譯 Lua 文件:
luac -o prog.lc prog.lua
lua prog.lc
錯(cuò)誤
Lua 遇見任何不可接受的條件時(shí)會(huì)產(chǎn)生錯(cuò)誤。例如:
local t = {}
-- 出錯(cuò)
t = t + 1
我們可以顯式的調(diào)用 error 函數(shù)來(lái)產(chǎn)生一個(gè)錯(cuò)誤,error 接受一個(gè)錯(cuò)誤消息作為參數(shù):
print 'enter a number:'
n = io.read('*n')
if not n then error('invalid input') end
assert 函數(shù)也可以產(chǎn)生錯(cuò)誤。assert 函數(shù)檢查第一個(gè)參數(shù)是否為 false,如果不為 false 就返回此參數(shù),如果為 false 就產(chǎn)生一個(gè)錯(cuò)誤。assert 的第二個(gè)參數(shù),錯(cuò)誤消息,是可選的。范例:
n = io.read()
assert(tonumber(n), 'invalid input: ' .. n .. ' is not a number')
pcall 函數(shù)可以捕獲錯(cuò)誤:
local ok, msg = pcall(function()
assert(false)
end)
print(ok, msg)
pcall 函數(shù)使用保護(hù)模式(protected mode)調(diào)用第一個(gè)參數(shù)(此參數(shù)為一個(gè)函數(shù)),如果被調(diào)用的函數(shù)執(zhí)行不存在錯(cuò)誤,pcall 返回 true 并返回被調(diào)用函數(shù)的所有返回值,如果被調(diào)用的函數(shù)產(chǎn)生了錯(cuò)誤,pcall 返回 false 并附帶上錯(cuò)誤消息。嚴(yán)格來(lái)說(shuō),錯(cuò)誤消息不一定需要是字符串:
local ok, err = pcall(function()
error({code = 502})
end)
print(err.code)
追蹤錯(cuò)誤
我們先看一個(gè)函數(shù):
function foo(str)
if type(str) ~= 'string' then
error('string expected')
end
-- ...
end
foo(1)
foo 函數(shù)需要一個(gè)字符串參數(shù),我們執(zhí)行上面的代碼:
lua: test.lua:3: string expected
輸出指出了錯(cuò)誤出現(xiàn)在 foo 函數(shù)中(因?yàn)?foo 函數(shù)調(diào)用了 error),而實(shí)際上,錯(cuò)誤是 foo 的調(diào)用者產(chǎn)生的,而非 foo 產(chǎn)生的。我們可以設(shè)置 level 來(lái)修正這個(gè)報(bào)錯(cuò):
function foo(str)
if type(str) ~= 'string' then
error('string expected', 2)
end
-- ...
end
error 函數(shù)的第二個(gè)參數(shù)為 level,用于指定報(bào)錯(cuò)的位置,level 值為 1 表示 error 的調(diào)用者,值為 2 表示 error 的調(diào)用者的調(diào)用者,以此類推。
pcall 只能返回錯(cuò)誤消息,很多時(shí)候我們需要完整的調(diào)用棧,這時(shí)可以使用 xpcall 函數(shù)。xpcall 函數(shù)可以接收一個(gè)消息 handler 作為參數(shù),在被調(diào)用函數(shù)出現(xiàn)錯(cuò)誤時(shí),消息 handler 會(huì)被調(diào)用,通過其就可以獲取到當(dāng)前調(diào)用棧的信息。
相關(guān)文章
基于 aLi Lua Web Server 的一個(gè)簡(jiǎn)單例子
這篇文章主要介紹了基于 aLi Lua Web Server 的一個(gè)簡(jiǎn)單例子的代碼,非常簡(jiǎn)單,推薦給大家。2015-03-03Lua協(xié)程(coroutine)程序運(yùn)行分析
這篇文章主要介紹了Lua協(xié)程(coroutine)程序運(yùn)行分析,本文講解分析了一段lua 協(xié)程代碼是如何運(yùn)行的,需要的朋友可以參考下2015-05-05Lua 操作 MongoDB 數(shù)據(jù)庫(kù)實(shí)例
這篇文章主要介紹了Lua 操作 MongoDB 數(shù)據(jù)庫(kù)實(shí)例,本文給出了修改后的lua-mongo API和具體的操作MongoDB 數(shù)據(jù)庫(kù)代碼,需要的朋友可以參考下2015-03-03lua中使用packagepath解決多個(gè)項(xiàng)目的路徑?jīng)_突問題
這篇文章主要介紹了lua中使用packagepath解決多個(gè)項(xiàng)目的路徑?jīng)_突問題,本文描述了問題的產(chǎn)生環(huán)境和原因,并給出了解決方法,需要的朋友可以參考下2015-04-04lua讀取redis數(shù)據(jù)的null判斷示例代碼
最近在工作中遇到了一個(gè)問題,通過查找相關(guān)資料才得知原因是因?yàn)榉祷亟Y(jié)果的問題,下面這篇文章主要給大家介紹了關(guān)于lua讀取redis數(shù)據(jù)的null判斷的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09