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自动发布
相关文章
相关标签/搜索