lua 學習之編譯

編譯

  1. lua 是解釋語言
  2. 但 lua 容許在運行源代碼前,先將源代碼編譯爲一種中間形式
  3. 區別解釋語言的主要特徵並不在因而否能編譯它們
    1. 在於編譯器是不是語言運行時庫的一部分
    2. 是否有能力執行動態生成的代碼

loadfile 函數

  1. dofile 函數是一種內置的操做,用於運行 lua 代碼塊git

  2. dofile 僅是作了 loadfile的輔助工做github

  3. loadfile 會從一個文件加載 lua 代碼塊express

  4. 但不會運行代碼,只是編譯代碼函數

  5. 而後將編譯結果做爲一個函數返回lua

  6. dofile 會引起錯誤spa

  7. loadfile 只會拋出錯誤值,但不處理錯誤code

function dofile(filename)
    -- assert 返回錯誤值
    local f = assert(loadfile(filename))
    return f()
end
  1. 發生錯誤時,loadfile 會返回 nil 及錯誤消息,可自定義錯誤消息
  2. 在須要屢次運行一個文件時,只需調用一次 loadfile ,屢次調用它的返回結果,也就是那個函數便可
  3. dofile 開銷則相比 loadfile大得多,由於 loadfile 只編譯一次文件

loadstring 函數

  1. 從一個字符串中讀取代碼
  2. 一樣會返回一個函數
  3. 開銷很大,由於在每次調用 loadstring 時都會編譯一次
  4. function 的寫法只在編譯對於程序塊時被編譯了一次
i = 0
f = loadstring("i = i + 1") -- 等效於 f = function() i = i + 1 end
f()
print(i) -- 1
f()
print(i) -- 2

-- dostring 完成加載並運行代碼
assert(loadstring(s))() -- 語法錯誤 "attempt to call a nil value"
  1. loadstring 編譯時不涉及詞法域
  2. loadsting 只在全局環境中編譯字符串,而非局部環境
i = 32
local i = 0
f = loadstring("i = i + 1; print(i)")
g = function() i = i + 1; print(i) end
f() -- 33 使用了全局變量
g() -- 1 使用了局部變量
  1. 能夠執行外部代碼
do
print("enter you expression:")
local l = io.read()
local func = assert(loadstring("return '" .. l .. "'"))
print("the value of your expression is " .. func())
end

do
print("enter function to be plotted(with variable 'x'):")
local l = io.read()
local f = assert(loadstring("return " .. l))
for i = 1, 20 do
    x = i
    print(x .. ":" .. string.rep("*", f()))
end
end
  1. loadfileloadstring ,有一個真正的原始函數 loadip

  2. loadfileloadstring 分別從文件和字符串中讀取程序塊內存

  3. load 接收一個「讀取器函數」,並在內部調用它來獲取程序塊字符串

  4. 讀取器函數能夠分幾回返回一個程序塊,load 會反覆調用它,直到它返回 nil (表示程序塊結束)爲止

  5. 只有當程序塊不在文件中,或者程序塊過大而沒法放入內存時,纔會用到 load

  6. lua 將全部獨立的程序塊視爲一個匿名函數的函數體,而且該匿名函數還具備可變長實參

  7. 與其餘函數同樣,程序塊中能夠聲明局部變量

loadstring("a = 1") -- 等效於 function(...) a = 1 end
f = loadstring("local a = 10; print(a + 10)")
f() -- 20
  1. 重寫讀取輸入示例,避免使用全局變量 x
print("enter function to be plotted (with variable 'x'):")
local l = io.read()
local f = assert(loadstring("local x = ...; return " .. l))
for i = 1, 20 do
    print(string.rep("*", f(i)))
end
  1. load 函數不會引起錯誤。在錯誤發生時,load 會返回 nil 以及一條錯誤信息
print(loadstring("a a"))
-- nil [string "a a":1 '=' expected nead 'a']
  1. loadfileloadstring 不會帶來任何反作用
  2. 它們只是將程序塊編譯爲一種中間表示,而後將結果做爲一個匿名函數來返回。
  3. 而並非加載了一個程序塊,或定義了其中的函數
  4. 函數定義是一種賦值操做,是在運行時才完成的操做。
-- 編寫一個 lua 文件,命名爲 foo
function foo(x)
	print(x)
end

-- 在 cmd 中的 lua 解釋器中輸入
f = loadfile("你存放 foo 文件的路徑")
print(foo()) -- nil
f() -- 定義函數
foo("test") -- test
  1. 執行外部代碼的一些操做
  2. 處理加載程序塊時報告任何錯誤
  3. 若是代碼不受信任,須要在保護環境(即以前提到的「沙盒」中執行這些代碼)

本篇文章由一文多發平臺ArtiPub自動發佈
相關文章
相關標籤/搜索