Lua代码规范

  每个语言都有他自己的代码规范,如何写好一个易懂又美观的代码,下面我们来学习一下。

空行

加空行:

  • 函数之间都要加空行;

  • 函数内部代码概念与逻辑之间,逻辑段落小节之间,都应该加空行;

  • 注释行之前。

不加空行:

  • 在一个函数体内,逻揖上密切相关的语句之间不加空行;

  • 多行注释解释参数的时候,注释之间不加空行。

空格

加空格:

  • ”and“,”or“等关键字前后留一个空格,便于辨析;

  • 逗号”,“后面要留一个空格;

  • 赋值操作符、比较操作符、算术操作符如”=“、 “==“、”~=“、”>=“、”<=“、”>“、”<“、”+“、”-“、”*“、”/“、”%“、”^“,等二元操作符的前后应当加空格;

  • if、for、while等关键字之后如果要加左括号”(“,关键字与左括号之间应留一个空格,以突出关键字;

不加空格:

  • 函数名之后不要留空格,紧跟左括号”(“;

  • 左括号”(” 向后紧跟,紧跟处不留空格;

  • 右括号”)“、逗号”,“、分号”;“,向前紧跟,紧跟处不留空格;

  • 字符串连接符”..“前后不加空格;

  • “:“,”.“,”[“,”]“这类操作符前后不加空格;

代码示例

  1. a > b and a or b -- 良好的风格

  2. a > b and a or b -- 不良的风格

  3. local a, b, c, max -- 良好的风格

  4. local a,b,c,max -- 不良的风格

  5. if a > b then -- 良好的风格

  6. max = a

  7. end

  8. if a>b then max=a end -- 不良的风格

  9. data = dataTable[index] -- 良好的风格

  10. data = dataTable [ index ] -- 不良的风格

  11. function(posX, posY) -- 良好的风格

  12. function (posX,posY) -- 不良的风格

长行拆分

  • 代码行最大长度宜控制在70至80个字符以内。代码行不要过长,否则眼睛看不过来,也不便于打印;

  • 长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。

  1. -- 良好的风格

  2. local newBuindingBtn = UI.newButton({

  3. text = btnName,

  4. x = self.x,

  5. y = self.y,

  6. parent = self,

  7. style = {

  8. normal = ResConfig.png.commonBtnBlue

  9. }

  10. })

  11. -- 不良的风格

  12. local newBuindingBtn = UI.newButton({text = btnName,x = self.x,y = self.y,parent = self, style = {normal = ResConfig.png.commonBtnBlue}})

  13. -- 良好的风格

  14. if veryLongerVariable1 >= veryLongerVariable2

  15. and veryLongerVariable3 <= veryLongerVariable5

  16. and veryLongerVariable4 <= veryLongerVariable6 then

  17. doo()

  18. end

  19. -- 不良的风格

  20. if veryLongerVariable1 >= veryLongerVariable2 and veryLongerVariable3 <= veryLongerVariable5 and veryLongerVariable4 <= veryLongerVariable6 then

  21. doo()

  22. end

命名规则

共性规则

  • 命名应当直观且可拼读,可望文知意;

  • 标识符的长度应当符合“min-length && max-information”原则;

  • 采用英文单词或单词组合,英文单词不要复杂,但用词需准确,切忌使用汉语拼音命名;

  • 切勿为了避免命名过长而随意截取单词,以丢失可读性;

  • 所有命名都不要与-x已有的命名风格冲突,例如不要以CC,UI开头;

文件命名

  • 所有Lua文件的命名时使用大驼峰法;

  • 根据文件的特性,一般以文件里的模块名或者类名作为同名文件名;

  • 确定命名前,请检查下,不要跟其他文件同名;

  • CCArmature.lua -- 不良的风格

  • UILayout.lua -- 不良的风格

类的命名

  • 所有类命名时使用大驼峰法;

  • 类名一般由”名词”或”多名词”组成,不要简写;

  • 根据类的特性,加上相关的后缀或者前缀;

  • 管理类 Manager

  • 缓存类 Cache

  • 控制类 Controller

  • 模块 Module

  • 网络类 Proxy

变量命名

  • 使用 “名词” 或是 “形容词+名词” 命名;

  • 使用小驼峰法命名;

  • 为了可读性,尽量避免变量名中出现标号,如value1, value2;

  • 不要出现仅靠部分字母大小写区分的相似的变量;

  • 除非是局部变量功能等价全局变量,不然局部变量不要与已有的全局变量同名;

  • 尽量不要使用已有的类名作为变量名;

  1. local data -- 良好的风格

  2. local oldData -- 良好的风格

  3. local newData -- 良好的风格

  4. local pairs = pairs -- 良好的风格

  5. local posx,posX -- 不良的风格

  6. local btn1,btn2 -- 不良的风格

  7. local TABLE = {} -- 不良的风格

  8. local uILabel -- 不良的风格

类的成员变量

  • 类的成员变量以”self.”开头,以区分于局部变量;

例如:

  1. function init()

  2. self.mainPanel = false -- 常用格式

  3. topPanel = false -- 这样是全局变量,占用全局资源,而且难以区分于局部变量

  4. ...

  5. end

全局变量

全局变量使用双下划线(““)开头以及结尾,中间的命名以名词拼接,或”形容词+名词”拼接,不同单词之间用(”“)隔开; 例如: _VERSION_CODE = "1.0.0.0"

局部变量

M常用做模块里面表示模块本身

  1. module("MainGame.Module.IntegrationTest.MapModule",package.seeall)

  2. local M = class(SceneView,"MapScene")

  • 数据的初始化

  1. function M:init()

  2. ...

  3. end

  4. ...

  5. return M

  • 引用进来的类或模块,用大驼峰法命名,引用路径统一带括号;

  1. module(“MainGame.Module.IntegrationTest.MapModule”,package.seeall)

  2. local M = class(SceneView,”MapScene”)

  3. local Surface = require(“xx.xx”)

  4. local TestButtonPanel = require(“xx”)

临时变量

  • 常用下划线”_”作为可以忽略的变量

  1. for _,v in ipairs(t) do print(v) end

  2. i,k,v,t --常做临时变量

  3. for k,v in pairs(t) ... end

  4. for i,v in ipairs(t) ... end

  5. mt.__newindex = function(t, k, v) ... end

常量,事件名的命名

常量,事件名所用单词均大写,单词用下划线(‘_‘)分割;

例如:

  1. -- 常量 默认宽度

  2. LIST_DEFAULT_WIDTH = 100

  3. -- 事件 添加到场景

  4. ADDED_TO_STAGE = getId()

枚举的命名

  • 枚举名命名,与类名命名一致;

  • 枚举值命名,与常量,事件名的命名一致;

例如:

  1. ControllerViewType = {

  2. SCENE = "SCENE",

  3. PANEL = "PANEL",

  4. POP = "POP",

  5. }

文件组织

文件描述

  • 文件开头加上此文件的简要功能作用描述;

  1. -- MapModule.lua

  2. --Author:xx

  3. --Email:xx@flamingo-inc.com

  4. --20xxxx xx:xx

  5. --Using:创建地图

  6. module("MainGame.Module.IntegrationTest.MapModule",package.seeall)

  7. ...

文件中变量的定义

如果在文件中需要多次使用的某些导入文件,可以在文件开头用局部变量存储导入信息,而不是在每次使用的时候都重新导入一次;

  1. ...

  2. local Surface = require("xx.xx")

  3. local TestButtonPanel = require("xx")

  4. function M:xx()

  5. local testBtn = TestButtonPanel.newCC()

  6. ...

  7. end

  8. function M:yy()

  9. local panel = TestButtonPanel.newCC()

  10. local surface = Surface.newCC()

  11. ...

  12. end

  13. ...

类变量的定义

  • 类中的成员变量需要在init中先声明,并赋予初始值,不允许不声明直接使用;

函数参数的定义

  • 所有函数的参数都用统一的params做参数,并加入如下格式的注释:

  1. --[[

  2. 普通按钮 可缩放 scale9

  3. @param #string text 按钮名称

  4. @param #table style 按钮样式

  5. ]]

  6. function UI.newButtonScale9(params)

  7. ...

  8. end

函数的定义规则

  • 函数的行数过长(大于 100 行)时,尽量拆分为多个子函数;

  • 函数中一些晦涩的部分,一定要加上注释;

注释的使用

  • 短小的注释用–;

  • 长注释用–[[]];

编码技巧

应该尽量使用local变量而非global变量

  • 全局变量实际是放入全局表中,每次调用是用传入变量名作为key去获取,而local变量是直接通过lua的堆栈访问的;

  • 在能用局部变量解决的地方,不要使用全局变量,这点很容易被忽略;

  • 多次重复使用的全局接口,可以用局部变量保存下再使用;

  • 比如需要多重遍历操作一个大表:

  1. for k1,v1 in pairs(tbl) do

  2. for k2,v2 in pairs(v1) do

  3. ...

  4. end

  5. end

  1. do

  2. local pairs = pairs

  3. for k1,v1 in pairs(tbl) do

  4. for k2,v2 in pairs(v1) do

  5. ...

  6. end

  7. end

  8. end

由于pairs是一个全局变量应用的函数,所以写法2在这里有稍微效率上的提升,但要是单层遍历的没有这个效果了。

临时变量的处理

  • 字符串的连接 .. 由于字符串的管理机制,字符串在使用..连接时,会产生新的对象。由于lua在VM内对相同的string永远只保留一份唯一copy。

例如:

  1. local description ""

  2. for i = 1,20 do

  3. description = description.."xxx"

  4. end

这样会生成21份string的copy,但实际上我们只需要最后那一份 如果是轻量级的简单连接还是可以使用的,因为影响不大,但要是大量的类似拼接,推荐使用string.format

类似于字符串的管理机制,表也存在类似的临时变量copy:

函数传参数

  1. function func({x,y})

  2. ...

  3. end

这种传参方式,每次都会生成一份copy,所以推荐以下的用法:

  1. function func(x,y)

  2. ...

  3. end

  4. function func({posX = x, posY = y})

  5. ...

  6. end

利用逻辑运算的短路效应

  • and or 的返回值是表达式中的左值或者右值,可用来简化代码

  1. function foo(arg)

  2. arg = arg or "default"

  3. ...

  4. end

但要注意当赋值为bool值时候,容易出bug

  • a = a or true -- 错误的写法,当 a 明确写为 false 的时候,也会被改变成 true 。

  • a = a ~= false -- 正确的写法,当 a 为 nil 的时候,被赋值为 true ;而 false 则不变。

另外,巧妙使用 and or 还可以实现类似 C 语言中的 ?: 三元操作:

  1. function max(a,b)

  2. return a > b and a or b

  3. end

这里相当于 return (a > b) ? a : b;

代码建议

代码的调试

用Luastudio工具调试,代替Sublime调试Lua代码;

复杂度和性能问题

写代码时尽可能写的简单,考虑性能时先做好推断,看看能提升多少,增加的复杂度以及造成的代码晦涩有多严重,然后再决定如何做;

函数的优化思考

  • 开销大的函数,调用次数低的话,可以不做优化;

  • 开销较小的函数,但调用频率很高,则从如何降低调用频率以及减少函数的开销两个角度去思考优化;

提交代码的检查

提交代码前,在svn commit中验证提交的代码,去掉或注释掉无关的代码,保证提交的代码无误;

表结构的引用

尽量减少表中的成员是另个表的引用;

猜你喜欢

转载自www.cnblogs.com/xingxia/p/lua_standard.html