跳转到内容

维基百科:Lua代码风格

本页使用了标题或全文手工转换
维基百科,自由的百科全书

结构元素

缩进与空格

使用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)

不要将模板赋值放在循环中。

参见