lua中的编译执行和错误
来源:互联网 发布:文华源码函数 编辑:程序博客网 时间:2024/06/05 00:47
1.lua中的dofile,loadfile,dostring和loadstring 函数
dofile函数想必都不陌生,我们经常在lua的的交互模式下直接用dofile(“”funcName“”)加载一个lua文件并运行,但实际上loadfile()才做了核心的工作,他会从文件加载一个代码块,但是不运行,仅仅编译该代码块,我们可以这样来定义一个dofile函数
function dofile(arg)local func = assert(loadfile(arg))return func()end处理一些简单的问题,比如有时候我们测试某个代码块的时候使用dofile更加简单,一次完成整个事情,但是loadfile更加灵活,例如可以让我自己处理错误消息(loadfile只会返回错误消息,自己并不处理),尤其在需要反复执行一个文件的时候,dofile需要每次进行编译,而loadfile仅仅需要编译一次,然后反复调用返回的函数就行了
下面看一下loadstring 和 dostring函数,类似loadfile函数,loadstring函数是从一个字符串中读取代码,并进行编译,例如在lua的加护模式下执行如下代码:
会有上述结果,一般当我们提供给用户自己输入一个lua程序给我们调用时,可以使用loadstring,但是这个函数开销较大,必须谨慎使用,类似于dofile,dostring也是对loadstring函数的一层封装,loadstring也不会引发错误,仅仅返回nil和错误消息,需要我们自己对错误消息进行处理。
其实,lua中有一个真正的读取函数 load()(例如io.read()),load接受一个读取器函数,对程序快进行一次或者多次读取,一般我们在程序块非常大,不能一次性载入内存的时候使用。lua中加载一个程序块仅仅是进行了编译,并返回一个带有变长参数的匿名函数作为中间形式,并没有对函数进行定义,lua中函数的定义是发生在函数调用的时候,假如我们有如下lua文件:
function foo()print("zhou,l,h")end我们利用loadfile来加载,并进行一些输出来看一下结果:
当我们加载之后foo依然是一个nil值,当我们运行加载后的函数后,foo被定义,此时打印出的是一个函数和他的地址,最后打印了调用foo的结果.当然我们可以对这几个函数做更多的工作,比如模仿其它高级语言,我们创建一个沙箱环境来运行可能有安全隐患的代码,从而使程序更贱健壮
2.lua中的错误处理
同样先来介绍几个函数:error,assert,pcall,xpcall
lua中任何未预期的条件都会产生一个错误,我们可以通过error函数显示的引发一个错误:error(“”this is a error“”),一般放在条件判断语句中,当不满足条件时调用,由于结构比较统一,我们可以用assert函数来代替,和其他高级语言的assert函数一样,在assert参数中指定出现错误时,返回的错误信息
当第一个参数为false或者nil时,把第二个参数当做错误信息返回,也可以不指定第二个参数。
当一个程序出现错误时,一般有两种选择方式,返回错误代码或者引发错误,一些容易避免的我们一般引发错误,但是一些不好避免的我们返回错误代码,在lua中我们使用pcall函数来对错误进行捕捉,我们可以把我们需要运行的代码封装在一个函数里面,通过pcall来调用该函数,
function foo()error("have a error")print("zhou,l,h")endif pcall(foo) then--返回真时的流程print("correctly ")else--捕捉到错误后的流程print("incorrectly")end其实就类似于c++或者c#中的 try{}catch{} 语句块
通常发生错误时,需要完整的错误信息,只是需要了解的当前的堆栈调用情况,而不仅仅是发火说呢个错误的位置,但是pcall返回错误信息时,已经销毁了调用栈的内容,
如果需要得到一个有意思的调用栈就需要在pcall返回前获取该信息,lua中提供了xpcall函数来完成此项工作,该函数除了接受一个被调用的函数之外,还接受第二个错误处理函数当参数,当错误发生时,lua会在调用栈展开前调用错误处理函数,这样,我们就能在这个函数中利用lua的debug库来收集错误信息了,主要用到两个函数debug.debug和debug.traceback,第一个函数提供一个提示符,让用户检查错误原因,第二个函数会根据调用栈来构建一个错误消息,任何时候都可以使用第二个函数来获取当前的调用栈信息,下面是一些列子:
function foo()error("have a error")endfunction f()foo()endres,message = pcall(f)print(res," ",message)
仅仅会打印出foo中的错误,没有显示f调用foo那部分的堆栈,下面我们使用xpcall来调用:
function foo()error("have a error")endfunction f()foo()endres,message = xpcall(f,function ()return debug.traceback()end)print(res," ",message) 下面是堆栈图:
显示了完整的堆栈信息。到此,lua中的错误处理和编译我们应该有了一定的概念,如果需要更深的了解,可以去看看lua的源码中相关函数的实现,博主水平有限,如有不正确的地方欢迎大家批评指出,晚安。
阅读全文
0 0
- lua中的编译执行和错误
- lua 编译、执行和错误
- Lua 编译-执行-错误
- Lua编译执行与错误 dofile loadstring
- Lua入门教程 7.编译、执行与错误
- lua的编译,执行和调试
- Lua程序设计笔记之四: 编译,执行与错误
- Step By Step(Lua编译执行与错误)
- Lua学习笔记 第八章 编译、执行与错误
- 7.lua学习笔记:编译、执行与错误
- 《lua程序设计》读书笔记 第8章:编译、执行与错误
- Lua编译错误小结
- (6)LUA程序设计-编译执行与错误(compile 、run & error)处理
- Lua程序设计第二版(笔记) 第八章编译、执行与错误
- 编译和使用Lua
- 初学Java编译和执行容易犯的错误
- Lua学习---编译生成lua和luac
- 7.编译、执行与错误
- Linux python3 安装Mayavi
- 解决问题:Cannot refer to the non-final local variable user defined in an enclosing scope
- •连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。 输入描述: 连续输入字符串(输入2次,每个字符串长度小于100)
- hanlp汉语言包
- Java实现邮箱激活账户实例
- lua中的编译执行和错误
- 无人驾驶好文
- 基于循环神经网络实现基于字符的语言模型(char-level RNN Language Model)-tensorflow实现
- SVM支持向量机
- 刷题--二叉树的镜像
- Linux系统-tcpdump常用抓包命令
- MySQL 分组
- 【Eternallyc】素数6N+1法
- jquery方法1