維基百科: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)

不要將模板賦值放在迴圈中。

參見