lua代码的检查

Posted 阿赵Unity3D技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua代码的检查相关的知识,希望对你有一定的参考价值。

现在做手机游戏,由于商店审核周期、用户下载的意愿等问题比较敏感,都很注重热更新的实现。其中很多人都会选择lua脚本作为代码热更新的手段。

作为弱类型的脚本,lua写起来是非常的轻松愉快,很自由。但由于过于轻松愉快,很多时候会导致一些写法上的问题。比如语法的错误,或者变量的声明问题,或者方法名和变量拼错了单词之类的问题,经常都会出现。如果是强类型或者需要编译的语言,这种错误是很容易就能发现。但作为lua脚本,你很有可能要到运行程序的时候,才会收到报错,或者甚至在运行的时候也没有任何报错,直到某个功能出现问题了,才能从检查代码里面发现问题。

我使用lua做了几个项目了,也遇到了类似的问题。

首先语法错误是最常见的,比如写if then之后,忘记写end了,或者写括号的时候最右边少写了一个括号之类。这种问题一般来说在运行代码的时候,会在require当前lua文件时就会报错,而且一般都有明确的报错行号,所以可以很快的发现。不过如果经常写错这些小问题,又要到运行的时候才能发现,那样也非常费时间。所以我们可以通过预编译的功能,在代码运行之前就做检查。预编译的实现对于不同的脚本编辑器是不一样的,可以自行百度一下。比如我是用sublime来写lua的,所以需要先做电脑上面安装lua运行环境,然后在SublimeTools——>Build System里面添加一个lua的编译环境(具体添加方法可以百度一下“sublime 编译lua”)。这样做写完lua代码之后,按一下Ctrl+B,就可以帮你检查一下当前的lua脚本有没有语法上面的报错。

最麻烦的是非语法报错。之前我的项目里面遇到过这样的问题。有些程序员在写业务逻辑的时候,忘记声明一个变量就直接用了,比如想读一个技能数据叫做skillData的做局部用途,本来应该是local skillData = GetSkillData(),但却忘记写local了,直接skiillData = GetSkillData()。然后刚好有另外一个类但名字就叫做skillData但,那么这个变量的内容,就把另外一个类给覆盖了……

熟悉lua语法的朋友应该知道造成这种问题的原因。由于lua是使用全局表_G来存储所有的类和全局表格的,我们require一个lua脚本,其实就是把脚本里面声明的全局类作为key,然后类的内容本身作为valve,存在了_G全局表里面。如果我们使用一个变量之前不做范围声明,比如local 或者self 或者this之类有限范围内的声明,它就可以是一个全局的变量,如果_G里面已经有这个名字的对应内容,原来的内容将会被覆盖了。

对于这种问题,我们很难通过工具去检查,只能用代码习惯来规避它。比如类名的首字母用大写,变量名的首字母用小写,局部变量名用 _ 开头之类。然后必须有声明变量再使用的习惯。

上面这种全局变量问题,有一些情况是可以查询出来的。举个例子,我们写了一个方法A,里面有一个变量a是有声明的或者从其他地方传入的,但我们在把方法A复制到方法B的时候,忘记去修改变量a的获取方式,导致变量a变成一个既没有声明又没有获取途径的变量。这时候,a就变成了从全局表_G里面查询的对象,一般来说会nil。这时候,我们的代码有可能并不会报错,因为nil作为变量的值传入是完全合法的,但可能会引起功能上的异常。

这个时候,假如我们在初始化lua的时候require一个叫做strict .lua的脚本(这个脚本在tolua有自带,在misc文件夹下)。那么在运行的时候,假如出现了需要从_G表里面查询一个没有预先声明过的名字的内容时,将会报错。比如上面的B方法里面的b变量,没有先local声明就直接用,将会报错。使用strict脚本来查错,将会限制一些写法,比如我们就不能在运行时临时往全局表添加内容了,只能通过require的方式去添加,还有一些比如喜欢用_来当作无用返回变量的存储的写法,也会报错,不过可以预先把_声明了就可以了。虽然一些写法会被限制,但我觉得那些写法本身的规范性就有待商讨,而由于有了限制,可以让我们的代码更规范而且容易发现错误,我觉得还是有很大的好处的。


以上是关于lua代码的检查的主要内容,如果未能解决你的问题,请参考以下文章

检查 Lua 中的字符串是不是为 nil 或为空

静态检查lua语法工具luacheck

lua重复执行一段代码

Lua篇静态代码扫描分析

为啥lua语言中使用全局变量就会造成内存泄漏呢??

是否可以在 Lua 代码中从 SQL 中提取数据?