Lua入门教程 7.编译、执行与错误

0x07编译、执行与错误

Lua虽然是一种解释性语言,但Lua允许在运行源码前,先将源码预编译成一种中间形式。

1.编译与执行

Lua提供了dofile loadfile两个接口来从文件里加载Lua的代码块,但它不会运行代码,而只是编译做对,然后将编译结果作为一个函数返回

function dofile (filename) 
    local f = assert(loadfile(filename))
    return f()
end

注:如果dofile失败,那么其中的assert就会引发一个错误


loadstringloadfile类似,但是不同的一点是,loadfile是对一个文件进行读取的而loadstring是对一个字符串来进行读取的。
loadstring功能非常的强大,但应该谨慎使用,因为他是一个开销较大的函数

f = loadstring("i = i + 1") --Code 1

上面的代码等价于下面的代码

f = function() i = i + 1 end --Code 2
  • Code1 和 Code2的代码是类似的,但是Code2的代码会快很多,因为它只在编译对应程序块时被编译了一次。而Code1却在每次调用loadstring()时都被重新编译。
  • Code1与Code2严格来说是不等价的,因为loadstring在编译时不涉及词法域
i = 32
local i = 0
f = loadstring("i = i + 1; print(i)")
g = function() i = i + 1; print(i) end
f() -->33
g() -->1

loadstring最大的用处是用来处理来自外部输入的代码,如用户自定义的程序

匿名函数

Lua将所有独立的程序块视为一个匿名函数的函数体,并且该匿名函数还具有可变长实参。例如loadstring(“a=1”)返回的结果等价于以下表达式:

function(...) a = 1 end

loadstring loadfile对传入的参数编译后将结果作为一个匿名函数返回。
如有一个foo.lua文件:

function foo (x)
    print(x)
end

然后执行下面的代码:

f = loadfile("foo.lua")

在此之后,函数完成编译,但是还没定义它。

print(foo) -->nil
f() -->定义了foo
foo("ok") -->ok

其它:loadlib函数加载指定的库,并将其直接链接入Lua

2.错误及错误处理

由于Lua是一种扩展语言,通常嵌入在应用程序中,因此在发生错误时它不能简单地崩溃或者退出


通过error来处理错误

print "enter a number:"
n = io.read("*number")
if not n then error("invalid input") end
--或者使用assert
--n = assert(io.read("*number"), "invalid input")

当一个行为发生异常时,通常有两种处理方法:1.返回错误代码(通常是nil) 2.引发一个错误(调用error)
如果需要在Lua中处理错误,则必须使用函数pcall来包装需要执行的代码

function foo()
    <some code>
    <some code> print(a[i]) --潜在的错误:a为需要打印的错误信息
    <some code>
end

然后用pcall调用foo

if pcall(foo) then
--执行时没有发生错误
<正常代码>
else
--foo发生错误,处理异常
<错误处理代码> end

猜你喜欢

转载自blog.csdn.net/yao_jianlun/article/details/51762536