维基百科:Lua代码风格
结构元素
缩进与空格
“ | And the Lord spake, saying: Thou shalt indent with four spaces, no more, no less. Four shalt be the number of spaces thou shalt indent, and the number of the indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. | ” |
——The Book of Armaments,[1] |
使用Tab缩进。以前维基百科的代码编辑器默认使用4个空格,但从bug 39616修复起都使用Tab缩进。试着限制每行的长度,方便使用小屏幕的人。
调用函数或者下标访问数组和字典时,避免添加多余的空格。在([, (, {和其对应项)的前后不要添加空格。
-- Yes:
hi = {1, 2, 3}
foo(hi[1], blah['a'])
-- No:
hi = { 1, 2, 3 }
foo( hi[ 1 ], blah[ 'a' ] )
blah ['b'] = hi [3]
foo (0, '')
控制流
不建议将多条语句放在一行,除非表达式极短。也试着避免将多条子语句放在同一行。
-- 是:
if 1 then
foo()
bar()
else
baz()
end
if 1 then foo() end
foo(); bar(); baz();
-- 否:
if 1 then foo(); bar(); else baz(); end
if 1 then foo(); bar(); baz();
else lorem(); ipsum(); end
foo(); bar(); baz(); spam(); eggs(); lorem(); ipsum(); dolor(); sit(); amet();
如果一行太长,你可以将长语句分割至多行并且保持缩进与开括号相同。如if语句,条件可以放在多行。
-- 示例:
hello = long_function_name(var_one, var_two,
var_three, var_four)
if ((condition1
or condition2)
and condition3
and condition4) then
foo()
bar()
baz()
end
命名常规
定义入口方法,使其展开参数,然后传入前缀下划线的同名方法。如果函数短并且简单,忽略这条规则。
在标准库中,包含多个单词的函数名通常被简单的连在一起(如setmetatable)。推荐camelCase(驼峰式命名)命名函数,以避免有歧义的函数名。
-- 参见此处代码:https://en.wikipedia.org/w/index.php?oldid=540791109
local p = {}
function p._url(url, text)
-- 在此写入代码
end
function p.url(frame)
-- 在 frame 之外指定参数并让它们通过 p._url()。返回结果。
-- 在此写入代码
return p._url(url, text)
end
return p
使用
高亮Lua代码
在模块之外(像讨论页)可以用<syntaxhighlight>标签加上lang="lua"
属性高亮代码。
<syntaxhighlight lang="lua">
--code snippet
function p.main()
return "Hello world"
end
</syntaxhighlight>
生成:
--code snippet
function p.main()
return "Hello world"
end
如果想要在行内显示代码的话,可以使用inline
属性。<syntaxhighlight lang="lua" inline>a = "foo"</syntaxhighlight>
生成a = "foo"
。
代码习惯
多用 local
Lua 代码中能不用全局变量则不用全局变量。这样可使导出整洁,同时不浪费全局变量查找的时间。
-- code snippet
local function fooHelper(arg1)
local a = {}
-- do something ...
return a
end
string.format()
string.format()
对于复杂字串的构造非常有用,但是对于一些简单任务而言就显得画蛇添足,只能降低运行效率。
不要用于简单字符串拼接
一般来说,在串接的元素数量不多于五个时,..
更加可读。如果格式化字符串中存在引号、方括号等成对的字符,则还要注意拆开这些组合的次数最多一次。
-- 一般情况
return string.format('%s%s%s<br/>', foo, bar, baz) -- 不要这样
return foo .. bar .. baz .. '<br/>' -- 要这样
-- 引号/方括号,但是没有跨过引号
foo = string.format('%s<th style="text-align: right;">%s</td></tr>', ret, pageNumberWithLink(args, class, 'ALL'))
foo = ret .. '<th style="text-align: right;">' .. pageNumberWithLink(args, class, 'ALL') .. '</td></tr>'
-- 发生嵌套的情况
-- 打开写的话会拆开两次引号。
bar = string.format('<tag title="%s" href="%s">%s</tag>', t, h, c)
-- 使用括号分组或可缓解阅读难度,但输入麻烦没什么意义。
bar = '<tag ' .. ('title="' .. t .. '" ') .. ('href="' .. h ..'"') .. '>' .. c .. '</tag>'
长文本构造
构造表格等大段文本时,仅应使用string.format()完成某个“小单元”的格式化,而使用..
与之前的字串连接赋值。
local builder = ''
for i, j in ipairs(foo)
-- 不要这样
builder = string.format('%s<foo bar="%s">%s</foo>', builder, fun(i), j)
-- 要这样做(容易看得出是在加后缀)
builder = builder .. string.format('<foo bar="%s">%s</foo>', fun(i), j)
end
如果你知道自己构造的文本非常大,那么考虑使用表格存放小段文本,最后拼接。这么做是因为Lua的字符串是不可变的,每次赋值构造拼接都会生成一个新的对象。
local builder = {}
for i, j in ipairs(foo)
-- 把这个“小单元”加进表格后面
builder[#builder+1] = string.format('<foo bar="%s">%s</foo>', fun(i), j)
end
final_string = table.concat(builder)
这样写的时候要切不可矫枉过正而把小单元拆开,写出把'<foo bar="'
、fun(i)
之类的小块一行行加进表格的面条式代码。
对模板格式命名
string.format()
的格式模板可以考虑命名成为一个局部变量,增加可读性。
-- 本来是这样
foo = string.format('<td title="剩余">%10g</td>', remaining)
-- 这样更好
local cell_td = '<td title="剩余">%10g</td>'
foo = cell_td:format(remaining)
不要将模板赋值放在循环中。