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
loadfile
和loadstring
,有乙個真正的原始函式load
loadfile
和loadstring
分別從檔案和字串中讀取程式塊
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']
loadfile
和loadstring
不會帶來任何***
它們只是將程式塊編譯為一種中間表示,然後將結果作為乙個匿名函式來返回。
而並不是載入了乙個程式塊,或定義了其中的函式
函式定義是一種賦值操作,是在執行時才完成的操作。
-- 編寫乙個 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 ...