当前位置:   article > 正文

(6)LUA程序设计-编译执行与错误(compile 、run & error)处理_lua脚本编译错误

lua脚本编译错误

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,加入请注明来源。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/658182
推荐阅读
相关标签
  

闽ICP备14008679号