Lua入門教程 7.編譯、執行與錯誤

0x07編譯、執行與錯誤

Lua雖然是一種解釋性語言,但Lua允許在運行源碼前,先將源碼預編譯成一種中間形式。

1.編譯與執行

Lua提供了dofile loadfile兩個接口來從文件里加載Lua的代碼塊,但它不會運行代碼,而只是編譯做對,然後將編譯結果作爲一個函數返回

function dofile (filename) 
    local f = assert(loadfile(filename))
    return f()
end

注:如果dofile失敗,那麼其中的assert就會引發一個錯誤


loadstringloadfile類似,但是不同的一點是,loadfile是對一個文件進行讀取的而loadstring是對一個字符串來進行讀取的。
loadstring功能非常的強大,但應該謹慎使用,因爲他是一個開銷較大的函數

f = loadstring("i = i + 1") --Code 1

上面的代碼等價於下面的代碼

f = function() i = i + 1 end --Code 2
  • Code1 和 Code2的代碼是類似的,但是Code2的代碼會快很多,因爲它只在編譯對應程序塊時被編譯了一次。而Code1卻在每次調用loadstring()時都被重新編譯。
  • Code1與Code2嚴格來說是不等價的,因爲loadstring在編譯時不涉及詞法域
i = 32
local i = 0
f = loadstring("i = i + 1; print(i)")
g = function() i = i + 1; print(i) end
f() -->33
g() -->1

loadstring最大的用處是用來處理來自外部輸入的代碼,如用戶自定義的程序

匿名函數

Lua將所有獨立的程序塊視爲一個匿名函數的函數體,並且該匿名函數還具有可變長實參。例如loadstring(“a=1”)返回的結果等價於以下表達式:

function(...) a = 1 end

loadstring loadfile對傳入的參數編譯後將結果作爲一個匿名函數返回。
如有一個foo.lua文件:

function foo (x)
    print(x)
end

然後執行下面的代碼:

f = loadfile("foo.lua")

在此之後,函數完成編譯,但是還沒定義它。

print(foo) -->nil
f() -->定義了foo
foo("ok") -->ok

其它:loadlib函數加載指定的庫,並將其直接鏈接入Lua

2.錯誤及錯誤處理

由於Lua是一種擴展語言,通常嵌入在應用程序中,因此在發生錯誤時它不能簡單地崩潰或者退出


通過error來處理錯誤

print "enter a number:"
n = io.read("*number")
if not n then error("invalid input") end
--或者使用assert
--n = assert(io.read("*number"), "invalid input")

當一個行爲發生異常時,通常有兩種處理方法:1.返回錯誤代碼(通常是nil) 2.引發一個錯誤(調用error)
如果需要在Lua中處理錯誤,則必須使用函數pcall來包裝需要執行的代碼

function foo()
    <some code>
    <some code> print(a[i]) --潛在的錯誤:a爲需要打印的錯誤信息
    <some code>
end

然後用pcall調用foo

if pcall(foo) then
--執行時沒有發生錯誤
<正常代碼>
else
--foo發生錯誤,處理異常
<錯誤處理代碼> end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章