编译
- lua 是解释语言
- 但 lua 容许在运行源代码前,先将源代码编译为一种中间形式
- 区别解释语言的主要特征并不在因而否能编译它们
- 在于编译器是不是语言运行时库的一部分
- 是否有能力执行动态生成的代码
loadfile 函数
-
dofile
函数是一种内置的操做,用于运行 lua 代码块git -
dofile
仅是作了loadfile
的辅助工做github -
loadfile
会从一个文件加载 lua 代码块express -
但不会运行代码,只是编译代码函数
-
而后将编译结果做为一个函数返回lua
-
dofile
会引起错误spa -
loadfile
只会抛出错误值,但不处理错误code
function dofile(filename) -- assert 返回错误值 local f = assert(loadfile(filename)) return f() end
- 发生错误时,
loadfile
会返回nil
及错误消息,可自定义错误消息 - 在须要屡次运行一个文件时,只需调用一次
loadfile
,屡次调用它的返回结果,也就是那个函数便可 - 而
dofile
开销则相比loadfile
大得多,由于loadfile
只编译一次文件
loadstring 函数
- 从一个字符串中读取代码
- 一样会返回一个函数
- 开销很大,由于在每次调用
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()) 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
-
loadfile
和loadstring
,有一个真正的原始函数load
ip -
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
- 执行外部代码的一些操做
- 处理加载程序块时报告任何错误
- 若是代码不受信任,须要在保护环境(即以前提到的「沙盒」中执行这些代码)
本篇文章由一文多发平台ArtiPub自动发布