維基百科: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)
不要將模板賦值放在迴圈中。