Project:模块

来自滚动的天空Wiki

本页面列举了Lua模块页面的代码的一些规范,遵守这些规范可以让代码更可读,同时也便于维护,有时还可以提高性能。

代码格式[编辑源代码]

变量命名[编辑源代码]

Lua内所有变量(包括类、函数)的命名应当清晰易懂

模块返回的那个变量一般命名为p,但如果是常用于其他模块使用的,则可以根据习惯命名。

返回的表中直接被#invoke调用的函数的第一个参数一般命名为frame,表示这是由MediaWiki传入的框架对象。

用于面向对象使用的类应当使用“大驼峰”式命名法,即每个单词首字母大写,并直接连起来,如BlockItemGameInstance

变量名、函数名称(包括类的方法)使用“小驼峰”式命名法,即第一个单词全小写,如getNametoImmutable

常量(除类、函数以及可变对象)通常全大写命名,单词用下划线_隔开,如GAME_VERSION

可以将全局变量或全局变量的字段同指针复制到局部变量,以更快地索引,这种情况下局部变量可以和全局变量同名。例如local assert = asserttinsert = table.insert

空白字符[编辑源代码]

空行[编辑源代码]

空行可以将代码清晰地分成多个部分。此外,多个函数(方法)之间一般也是需要换行的

空格[编辑源代码]

为了使得代码更加美观,以下情况下,建议空格

  • 运算符之间,例如c = a + b
  • 用逗号分隔的多个变量之间,例如tonumber('32', 7)return a, bfor k, v in pairs(t) do
    • 注意:函数名称和参数之间不空格,但紧接字符串字面量、省略括号的情况除外。如f(32)不建议写成f (32)print 'Hello'不建议写成print'Hello'
  • 单行注释的两个横线之后建议加一个空格。如代码后同一行内加入注释,两个横线之前建议加至少两个空格。

缩进[编辑源代码]

尽管Lua不像Python等语言强制缩进,但为了增强代码可读性,仍然建议缩进

每一级缩进一般使用“制表符”(在代码编辑器中按键盘上的Tab键,手机版可能无法直接输入制表符,可以复制代码中已有的制表符)。另外如果由于缩进过多导致代码难读的话,可以将整个代码统一为两个空格的缩进。

此外,对于MediaWiki库的mw.html对象,可以在链式调用中根据层次逻辑调整缩进。

一个Lua页面内不建议混用不同类型(制表符、空格)缩进

注释[编辑源代码]

注释用于在代码中记录版权协议、函数用法或提醒编辑者等内容,使得读者更加能够理解注释内容。注释可以用于:

  • 阐明函数的返回值类型和用途,以及参数的类型和用途
  • 将不再需要的代码注释掉。本站使用ACEeditor编辑代码,选中文字并按Ctrl+/可快速将代码注释掉。
  • 说明代码中的逻辑。

此外,注释不应当“说废话”。例如x = x + 1 -- 将x增加1是没有意义的。

代码逻辑[编辑源代码]

好的代码可以让模块既能便于维护又能降低开销,且能充分发挥Lua的优势。

  • 不允许定义或修改全局变量(包括函数)。对于需要多次使用的全局变量(包括表的字段),可以将其存储为同名局部变量。
  • 禁止频繁连接字符串,尤其是追加性的连接。每连接一次字符串都会生成一个新的字符串对象,并将旧的对象作为垃圾收集。因此请不要在循环中多次使用..给字符串追加内容(比如s = s .. content),否则会多次构建并回收字符串对象。可以先将多个字符串追加到一个数组中,最后使用table.concat连接。此外,如果是按照一定格式和参数连接字符串的,可以使用string.format。需要注意:可以在一条语句中使用..将多个字符串串起来,如'宽度为' .. width ... ',高度为' .. height .. ',总面积为' .. (width * height),这种情况Lua是一次性连接的,不会多次构造字符串对象,而且比string.format还要快。
  • 如果需要频繁给数组最后面追加内容,比如要给数组t后追加值v,请使用t[#t + 1] = v而不是table.insert(t, v)。Lua自带的运算符永远是比函数调用更快的。
  • 善用二元运算符。判断某个值是否为nil,应当尽可能将其作为布尔值用作条件,而不是与nil值进行比较。例如,设置函数参数默认值时,假如参数frame的默认值为mw.getCurrentFrame(),应当使用frame = frame or mw.getCurrentFrame(),而不是if frame==nil then frame = mw.getCurrentFrame()
    • 当然,有时确实需要准确判断其是否为nil而不为false。例如,判断表t是否为空(忽略元表),应使用next(t) == nil
  • 对于大量的table形式储存的数据,应当存储在单独的页面,然后使用mw.loadData而非require获取数据,这样有助于提高性能。注意:使用mw.loadData导出的数据对象是只读的,可以正常访问字段并迭代,但不能修改字段,也不能够正常进行取长操作(#)或调用nextunpack等函数。不建议把数据对象进行一次深拷贝(deep copy)。