lua代码风格
命名:
命名
- 驼峰命名法:
- 小驼峰式命名法:第一个单字以小写字母开始;第二个单字的首字母大写,例如:
firstName
、lastName
。 - 大驼峰式命名法:每一个单字的首字母都采用大写字母,例如:FirstName、LastName、CamelCase,也被称为Pascal命名法。
- 小驼峰式命名法:第一个单字以小写字母开始;第二个单字的首字母大写,例如:
- 下划线命名法
- 小下划线命名法:所有字母均为小写,例如登录按钮:login_btn。
- 大下划线命名法:所有字母均为大写,常见于常量,例如:最小间隔时间MIN_GAP_TIME。
采用驼峰法或者下划线命名法都是OK的,只用一种命名即可。
变量名长度
通常作用域范围更大的变量名要比作用域范围更小的变量名具有更多的秒速信息。例如:i
经常用于循环中充当计数变量,而将其作为全局变量使用容易导致诸多问题。
变量命名
- 对于变量(包括函数),小驼峰式命名法或者下划线命名法是比较好的选择,例如:
lastFrame
:表示上一帧的图片。 - 对于boolean类型的变量,通常前缀会加上
is
来更方便理解,eg:isPlay
:表示是否播放
常数命名
lua里面没有严格的常数定义标识符,常数一般采用大写下划线命名法。比较醒目。eg:MAX_LENGTH
类名
为了不和变量名和方法名混淆,类名通常用大驼峰式命名法。eg:TouchManager
:表示触摸管理类
包和模块名
包名和模块名通常比较短,并且全部小写,单词并没有下划线区分。eg:lfs
:表示文件读取库:Lua File System,lxp
:表示Lua XML Parser
文件名
通常为了不与类名混淆,对于文件名,经常使用小驼峰命名法或者下划线命名法。
作用域:
lua的作用域以关键字end进行标识,对于变量,鉴于全局变量的危险性,有一个原则:一切能使用local
修饰的情况下,使用local
进行修饰。原因如下:
- 使用local的变量会在作用域结束时释放其内存
- 使用local的变量会比全局变量的存取更快
- 全局变量会污染全局的命名空间,可能会导致诡异的bug出现
这边有一些小技巧
-
使用
do .. end
可以明确限定局部变量的作用域。
eg:local v do local x = u2*v3-u3*v2 local y = u3*v1-u1*v3 local z = u1*v2-u2*v1 v = {x,y,z} end -- x,y,z的作用域结束,被系统清理 local count do local x = 0 count = function() x = x + 1; return x end end -- x的作用域结束,被系统清理
模块
lua中有一个叫做modle的共有函数,此函数的作用是将一组变量和函数打包在一个模块名下,便于其他文件require。但是其会创建一个公共变量,并且这个公共变量中的所有细节都会暴露出来。这其实十分不符合面向对象的规范。以下有一种办法可以避免这个问题,即不采用module函数进行打包。
eg:
-- hello/mytest.lua
local M = {} -- 私有变量
local function test() print(123) end
function M.test1() test() end
function M.test2() M.test1(); M.test1() end
return M -- 关键
导入模块:
local MT = require "hello.mytest"
MT.test2()
Lua内没有类这个变量类型,但是通过Lua的metatable可以轻松实现类的继承,多态等等特性。关于Lua中设计类的sample:
Player = {}
Player.__index = Player
function Player.New()
local obj = {name = "default"}
setmetatable(obj,Player)
return obj
end
注释
注释通常用在函数接口,或者复杂,精巧的逻辑上.通常在--
前加上一个空格。eg:
return nil -- not found (建议)
return nil --not found (不建议)
处于代码的精简考虑,注释通常用于函数接口,或者复杂的一些逻辑。
eg:
-- Swap the variable.
-- @param x:xxx
-- @param y:xxx
-------------------------------------
function swap (x, y)
local temp = x
y = x
x = temp
end
一些用法建议
-
判断真假
-- 不推荐 if obj ~= nil and willBreak == false then -- ... end -- 推荐 if obj and not willBreak then -- ... end
reason:
Lua在逻辑判断时将所有非false和nil的逻辑判断视为真,反之视为假,不需要再与布尔值和nil进行比对。但是,在需要对false和nil进行区分时,需要写明 ==:obj == nil和obj == false。
-
默认缺省参数的实现,
param = param or defaultValue
eg:function setName(name) name = name or 'defaultName' -- ... end
reason:
or会在第一次为true的时候断路,返回其判断的最后一个值。所以当name为空时,name or ‘defaultName’返回为’defaultName’,这会将name的值自动设置为defaultName
-
一行代码实现表的拷贝
u = {unpack(t)}
-
一行代码判断表是否为空
用#t == 0并不能判断表是否为空,因为#预算符会忽略所有不连续的数字下标和非数字下标。
正确做法是:if next(t) == nil then -- 表为空 -- ... end
reason:
因为表的键可能为false,所以必须与nil比较,而不直接使用~next(t)来判断表是否空。
-
更快的插入代码
-- 更慢,不推荐 table.insert(t, value) -- 更快,推荐 t[#t+1] = value
reason:[]和#避免了高层的函数调用开销。