Lua基础 编译、运行、错误解决
发布时间:2021-11-21 19:00:21 所属栏目:PHP教程 来源:互联网
导读:尽管Lua是一门解析型的语言,但是在运行前也会被编译成某个中间状态。一门解析型的语言需要编译,这听起来有点不合常理。但是,实际上,解析型语言的与众不同,不是说它不需要编译,而是说它把编译作为其运行时的一部分,因此,它就可以执行各种来自外部的代
尽管Lua是一门解析型的语言,但是在运行前也会被编译成某个中间状态。一门解析型的语言需要编译,这听起来有点不合常理。但是,实际上,解析型语言的与众不同,不是说它不需要编译,而是说它把编译作为其运行时的一部分,因此,它就可以执行各种来自外部的代码(例如网上的)。也许因为Lua中存在的如dofile 这样的函数,才使Lua可以被称为一门解析型语言。 1. 编译 之前我们介绍了dofile 来执行代码块,但是dofile 只是一个辅助函数。这里介绍一下loadfile 函数,它会从一个file中加载语句块,但是不运行;而是仅仅编译并作为一个函数返回。loadfile 不会像dofile 那样在运行时直接报错退出,而是返回错误码,这样我们就可以根据错误码做相应的处理。我们可以像下面这样定义dofile,这也可以看出dofile 和loadfile 的区别 function dofile (filename) local f = assert(loadfile(filename)) return f() end 注意,assert 可以使loadfile 发生错误时,报错退出。 dofile 在处理有些简单的任务时,使用起来比较方便,只需要一次调用,它会完成所有的操作(编译,运行啥的)。但是,loadfile更加灵活。发生错误的时候,loadfile 会返回nil + 'err_msg',我们可以根据实际情况对错误做出相应的处理。除此之外,如果想要运行一个file多次,可以先调用一次loadfile,然后调用loadfile 返回的结果多次,就可以了。这比调用几次dofile 开销要小很多,因为loadfile 只会执行一次编译,而dofile 每次都用都要编译。 loadstring 跟loadfile 差不多,区别是从一个string中加载代码块,而不是从file中。例如: f = loadstring("i = i + 1") f 是loadstring 的返回值,应该是function类型, 调用的时候,会执行i = i + 1 : i = 0 f(); print(i) --> 1 f(); print(i) --> 2 loadstring 函数功能非常强大,但是运行起来,开销也不小,并且有时会导致产生一些莫名其妙的代码。因此,在用loadstring 之前,先考虑下有没有更简单的办法。 下面这行代码,不太好看,但是很方便。(不鼓励这种调用方法) loadstring(s)() 如果有语法错误,loadstring 会返回nil + 类似‘attempt to call a nil value’这样的err_msg。如果想获取更详细的err_msg,那就需要用assert : assert(loadstring(s))() 下面这样的使用方式(对一个字面值string使用loadstring),没什么意思, f = loadstring("i = i + 1") 粗略的等价于: 但是,也不是完全相同,且继续往下看。第二种方式的代码运行起来更快,因为它只需要编译一次,而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 g 函数处理的事局部变量i , 而f 函数处理的是全局变量i ,loadstring 总是在全局环境中进行编译。 loadstring 最典型的用途是:运行外来代码,例如网络上的,别人的。。。注意,loadsting 只能load语句,不能load表达式, 如果你想算一个表达式的值,那么前面要加上一个return 来返回给定表达式的值。下面是一个示例帮助理解: print "enter your expression:" local l = io.read() local func = assert(loadstring("return " .. l)) print("the value of your expression is " .. func()) 看一下运行情况:(注意第一个为什么报错了,想想什么才叫表达式) loadstring 返回的就是一个普通的函数,可以多次调用: 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 -- global 'x' (to be visible from the chunk) print(string.rep("*", f())) end (string.rep 函数复制一个string给定的次数),下面是运行结果: 如果我们在深究一下,其实不管loadstring 也好,loadfile 也好,Lua中最基础的函数是load 。loadfile 从一个file中加载代码块,loadstring 从一个string中加载代码块,而load 调用一个reader函数来获取代码块,这个reader 函数分块返回代码块,load 调用它,直到它返回nil 。我们很少使用load 函数;通常只有在代码块不是位于一个file中,但是又太大了,不适合放到内存中(如果适合放到内存中,那就可以用loadstring 了)的时候,才会用load 。 ![]() (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |