滚动的天空Wiki:模块

来自滚动的天空Wiki

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

变量命名[编辑]

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

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

对于需要返回的表中直接被#invoke调用的函数,其第一个参数一般命名为frame

对于面向对象使用的类,应当使用“大驼峰”式命名法,即每个单词首字母大写,并直接连起来,如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页面内不允许混用不同类型(制表符、空格)缩进

注释[编辑]

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

  • 阐明函数的返回值类型和用途,以及参数的类型和用途
  • 将不再需要的代码注释掉。
  • 说明代码中的逻辑。

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

代码内容[编辑]

为提高性能、使得代码易于维护,编写代码时请注意:

  • 不允许定义或修改全局变量(包括函数)。对于需要多次使用的全局变量(包括表的字段),可以将其存储为同名局部变量。
  • 对于复杂的HTML标签,请使用mw.html库(见Help:Lua/mw.html)。
  • 禁止频繁连接字符串,尤其是追加性的连接。对于需要给字符串追加内容的,请使用字符串数组,然后最后使用table.concat连接。按照一定格式和参数连接字符串的,可以使用string.format
  • 如果需要频繁给数组追加内容,比如要给数组t后追加值v,请使用t[#t + 1] = v而不是table.insert(t, v)
  • 善用二元运算符。判断某个值是否为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获取数据,这样有助于提高性能。注意:使用mw.loadData导出的数据对象是只读的,可以正常访问字段并迭代,但不能修改字段,也不能够正常进行取长操作(#)或调用nextunpack等函数。不建议把数据对象进行一次深拷贝(deep copy)。

示例[编辑]

本页用一些简短的模块来举几个实际的例子,来讲述格式。在代码中,使用注释进行解释。

-- 这个表是最终需要返回的,因而命名为p。
local p = {}
local getArgs = require "Module:Arguments".getArgs

-- 将全局变量tostring复制到局部变量tostring中,这样调用时可以提高性能。
local tostring = tostring

function p._fullurl(args)
	-- 赋值符号“=”两边都应该加一个空格。
	local args = mw.clone(args)
	local onlyurl = args.onlyurl == '1'
	args.onlyurl = nil
	local title = args['title'] or args[1] or tostring(mw.title.getCurrentTitle())
	if title == '' then
		title = tostring(mw.title.getCurrentTitle())
	end
	local url, text
	if args[3] then
    	-- 对于有多个参数的函数调用,多个参数用空格隔开。
		url = tostring(mw.uri.fullUrl(title, args[2]))
		text = args[3]
	else
		text = args['text'] or args[2] or args[1] or title
		args.title = nil
		args.text = nil
		args[1] = nil
		args[2] = nil
	    url = tostring(mw.uri.fullUrl(title, args))
	end
    local plainlink = '<span class="plainlinks">[' .. url .. ' ' .. text .. ']</span>'
    if onlyurl then
		return url
	else
		return plainlink
	end
end

-- 多个函数之间应当空行。
-- 该函数是#invoke直接调用的函数,其第一个参数是一个框架对象,命名为frame。
function p.fullurl(frame)
	frame = frame or mw.getCurrentFrame() -- 参数frame的默认值。
	local args = getArgs(frame)
	return p._fullurl(args)
end

function p._fullurl2(title, paid, text)
    return '<span class="plainlinks">[' .. tostring(mw.uri.fullUrl(title,paid)) .. ' ' .. text .. ']</span>'
end

-- 最后一个return语句前面空一行。
return p