赞
踩
1.编译问题
----------------------------
----------------------------
首先我们谈一下编译的问题,LUA的执行,是将源代码转换成中间代码的形式执行的。
说到这里,也许会有不少人会问,LUA不是一种解释型语言,没错!LUA就是一门解释型动态语言脚本。其实区别一门语言是否为解释型语言,关键在不在于它是否被编译,而是它的编译器是否是运行时库的一部分,是否具备动态执行代码的能力。所以LUA是代码是需要被转成中间代码被LUA编译器执行的。
1.1LUA当中的常见编译函数
1.1.1 loadfile
LUA中,有dofile这样子函数,用于加载LUA代码文件,用法:dofile(filename), eg.dofile('xxx.lua');但其实dofile是调用了更深层的loadfile函数,与dofile类似,loadfile同样是用于加载编译一个代码块(chunck),但是除此之外loadfile还返回一个函数,同时如果编译出错,loadfile还会返回nil及相关错误信息。dofile调用loadfile的代码如下:
funciton dofile(filename)
local f = assert(loadfile(filename));
return f();
end
说明:1.assert用判断loadfile是否成功,有点像java/javascript里边的一个try{}catch{},用以引发错误信息。
2.dofile相对loadfile来说,每次调用,都需要重新编译一次被加载的代码块,而一次调用loadfile可以多次调用loadfile返回的函数引用。
1.1.2 loadstring
与loadfile类似,loadstirng 是用于加载lua代码块的字符串形式,并返回由该代码块组成的一个函数。
如:f = loadstring("i = i+1");
i = 0;
f() -->1
f()-->2
上面等价于
i = 0;
loadstring("i = i+1")( );-->1
loadstring("i = i+1")( );-->2
为了让错误显示得更清楚,我们可以为loadstring 的返回值加上 assert,即 assert(loadstring(s))()的形式
LUA将所以有独立的代码块都看成是一个匿名函数的函数体,而函数有可变参数这个特征(前面讲到的三大特征之一),所以loadstring函数所返回的函数,也允许传入参数。只需要在loadstirng(s)的s当中声明一个local变量用于保存可变参数,即可
f = loadstring("local xx = ... return xx "); f('hello') -- hello
------------------------------------------
注:f = loadstring('i = i+1') 基本上等价于 f = function() i = i+1 end
但是两者有极大的区别:
1.从词法域上来讲,loadstring 的方式,不涉及词法域,举例如下
i = 32
local i = 0
f = loadstring("i = i+ 1");
g = function() i=i+1 end;
f() --33
g() -- 1
2.从编译次数的角度来说,loadstring 每次调用都要重新编译一次,而function的形式,只编译一次。
1.1.3 load
与loadfile和loadstring相比,load函数有所不同。loadfile和loadstring 是分别从文件和字符串中读取程序块,但load则不同,如果加载的代码块过大,内存空间不够,用load则可以解决问题,它接收一次读取器函数,可以将一个程序块分多几读取,通过反复调用“读取器函数”,直到返回nil为止。
1.1.4 loadlib
众所周知,动态链接机制并非ansi c 标准的一部分,LUA用C编写的,不会包含无法用ANSI C实现的所有机制,但是动态链接机制除外,LUA将动态链接机制作为实现其他机制的母机制,通过动态机制,LUA可以加载任何LUA不支持的机制。
LUA加载动态链接库,主要用到函数package 下的loadlib,用法如下
local dynaLinkLibPath = ''/usr/local/lib/lua/5.0/socket.so' --linux下动态链接库后缀为so
local f = package.loadlib(path,'luaopen_socket');
package.loadlib通过指定加载库的路径,以及C函数名,返回一个LUA函数,用以被LUA代码调用。loadlib将结合我们后面要讲的require函数使用,require用于搜索指定库,loadlib用于加载搜到的库。
2.错误处理,异常封装,错误跟踪
2.1 LUA当中错误处理一般情况是
f = io.open(file);
if not f then
<error code here>
else
....
end
当然LUA提供了一个内建引发错误的函数,即上面讲到的assert函数
它接收到两个参数,第一个参数是lua的代码块,可以是一个表达式,一个函数调用的返回结果,第二个参数是一个字符串,用于提供 第一个参数代码执行时出错的提示
2.2异常封装
LUA提供一种pcall保护模式,pcall是一个函数,参数是一个函数,pcall返回两个值,第一个是函数参数是否调用成功,调用失败返回false,否则返回true.第二个参数是调用失败的错误信息。
local status ,err = pcall(function() error({code=500}) end);--可以自定义出错代码
print(err.code)--打印出错代码
2.3 错误跟踪
error()函数,可以接收一个字符串参数,用于提示出错原因,如error("the wrong string unexpected!!");,也可以接收两个参数,第一个参数用于提示出错原因,第二个参数用于表示具体出错的级别,可以跟踪错误出现的位置。举例如下:
function fuck(s)
if type(s) ~= 'string' then
error('string expected!!')
else ....
end
如果主函数调用了fuck()函数,并传入一个122number类型的数值,fuck将出错,但是并不能显示出错的层次,并不知道出错在哪里,所以将上面代码改成
function fuck(s)
if type(s) ~= 'string' then
error('string expected!!',2)
else ....
end
注:在error函数加入第二个参数2,那么出错时将提示具体出错的位置,便于调试跟踪!!!
完毕!!下节将讲解lua程序设计基础篇的最后一小节,内容也是相当重要!!也难理解!!
----------------好了---本节到此结束,下一节将讲解-(7)LUA程序设计-协同程序(coroutine)------------
LUA技术交流群,请加Q群:139315537,加入请注明来源。
(1)LUA程序设计-开篇(beginning)(2012-07-28 00:47) (2)LUA程序设计-类型与值(type & value)(2012-07-28 23:12)
|
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。