lua 學習之編譯

2022-07-05 14:30:14 字數 3487 閱讀 8030

lua 是解釋語言

但 lua 允許在執行源**前,先將源**編譯為一種中間形式

區別解釋語言的主要特徵並不在於是否能編譯它們

在於編譯器是否是語言執行時庫的一部分

是否有能力執行動態生成的**

dofile函式是一種內建的操作,用於執行 lua **塊

dofile僅是做了loadfile的輔助工作

loadfile會從乙個檔案載入 lua **塊

但不會執行**,只是編譯**

然後將編譯結果作為乙個函式返回

dofile會引發錯誤

loadfile只會丟擲錯誤值,但不處理錯誤

function dofile(filename)

-- assert 返回錯誤值

local f = assert(loadfile(filename))

return f()

end

發生錯誤時,loadfile會返回nil及錯誤訊息,可自定義錯誤訊息

在需要多次執行乙個檔案時,只需呼叫一次loadfile,多次呼叫它的返回結果,也就是那個函式即可

dofile開銷則相比loadfile大得多,因為loadfile只編譯一次檔案

從乙個字串中讀取**

同樣會返回乙個函式

開銷很大,因為在每次呼叫loadstring時都會編譯一次

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"

loadstring編譯時不涉及詞法域

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 使用了區域性變數

可以執行外部**

do

print("enter you expression:")

local l = io.read()

local func = assert(loadstring("return '" .. l .. "'"))

print("the value of your expression is " .. func())

enddo

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()))

endend

loadfileloadstring,有乙個真正的原始函式load

loadfileloadstring分別從檔案和字串中讀取程式塊

load接收乙個「讀取器函式」,並在內部呼叫它來獲取程式塊

讀取器函式可以分幾次返回乙個程式塊,load會反覆呼叫它,直到它返回nil(表示程式塊結束)為止

只有當程式塊不在檔案中,或者程式塊過大而無法放入記憶體時,才會用到load

lua 將所有獨立的程式塊視為乙個匿名函式的函式體,並且該匿名函式還具有可變長實參

與其他函式一樣,程式塊中可以宣告區域性變數

loadstring("a = 1") -- 等效於 function(...) a = 1 end

f = loadstring("local a = 10; print(a + 10)")

f() -- 20

重寫讀取輸入示例,避免使用全域性變數 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

load函式不會引發錯誤。在錯誤發生時,load會返回nil以及一條錯誤資訊

print(loadstring("a a"))

-- nil [string "a a":1 '=' expected nead 'a']

loadfileloadstring不會帶來任何***

它們只是將程式塊編譯為一種中間表示,然後將結果作為乙個匿名函式來返回。

而並不是載入了乙個程式塊,或定義了其中的函式

函式定義是一種賦值操作,是在執行時才完成的操作。

-- 編寫乙個 lua 檔案,命名為 foo

function foo(x)

print(x)

end-- 在 cmd 中的 lua 直譯器中輸入

f = loadfile("你存放 foo 檔案的路徑")

print(foo()) -- nil

f() -- 定義函式

foo("test") -- test

執行外部**的一些操作

處理引導程式塊時報告任何錯誤

如果**不受信任,需要在保護環境(即之前提到的「沙盒」中執行這些**)

LUA學習之編譯

cd src make linux gcc o2 wall dlua compat all dlua use linux c o lua.o lua.c gcc o lua lua.o liblua.a lm wl,e ldl lreadline usr lib gcc x86 64 redhat ...

Lua學習 編譯生成lua和luac

眾所周知,lua是一種強大的指令碼語言,並且這種語言是用c語言實現的。為什麼要學習這門語言?因為它可以增強我看c語言 的功底。我下的lua版本是lua5.3,關於lua5.3的簡介如下 下好了,該怎麼編譯?開啟makefile,於是看到關鍵的一行 plats aix bsd c89 freebsd ...

Lua學習 編譯生成lua和luac

眾所周知,lua是一種強大的指令碼語言,並且這種語言是用c語言實現的。為什麼要學習這門語言?因為它可以增強我看c語言 的功底。我下的lua版本是lua5.3,關於lua5.3的簡介如下 下好了,該怎麼編譯?開啟makefile,於是看到關鍵的一行 plats aix bsd c89 freebsd ...