Lua 5.1 添加对
模块(module)和包的支持,模块用来管理组织代码结构。
介绍
- 一个代码
模块(module)就是一个程序库(或函数的集合)- 模块通常表现为
表(table),包含函数、版本和作者等信息 - 使用
.来访问模块中的函数 - 通过
require来加载模块,参数是模块名(不包括后缀),通常用 local 变量保存 require 的返回值 - 示例:
local cjson = require "cjson" -- 加载 cjson 模块
- 模块通常表现为
- 创建一个模块最简单的方法是:创建一个
table,并将所有需要导出的函数放入其中,最后返回这个table - 开发时,建议将模块的函数 local 化,加快程序的执行速度
模块示例
test.lua模块
local _M = {version='0.1'} -- 定义表
local function get_name()
return "World!"
end
function _M.greeting()
print("Hello " .. get_name())
end
return _M -- 返回模块main.lua主函数
local t = require("test")
t.greeting()- 运行
$ luajit main.lua
Hello World!特性
- 封装,通过表封装为对象,所有的变量和函数都是公开的,不存在 private/public 的特性
local x = {}
x.name = 'xianbin'
x.get_name = function() ... end-
多态,即表的动态性,可以随时替换
-
继承,Lua 里使用
原型(prototype)模式实现,通过如下方式实现元表(metatable)描述了表的基本行为,类似于 Python 操作符的重载,使用__index原方法重载 Lua 里查找 key 的操作(即table.key)- 函数
setmetatable(t, meta)把表 t 的原表设置为 meta 并返回 t- 若 t 里设置了
__index方法,那么对 t.key 的操作同样作用到 meta.key 上(即meta.key) - t 克隆了表 meta 的所有成员,表 meta 成为了表 t 的
原型
- 若 t 里设置了
-
test.lua 示例
local _M = {} -- 定义原型对象
function _M.say() -- 添加函数
print('hi')
end
local mt = { __index = _M } -- 定义原表
local obj = setmetatable({}, mt) - 设置原表
obj.say() -- 执行原型操作
local obj = setmetatable({}, {__index = _M}) -- 合并的写法
-- 一般添加字段的写法
function _M.new()
return setmetatable({name='x'}, mt)
endself
- Lua 访问表的成员函数可以通过
:,比.调用时多传入一个self参数 self类似于 Python Class 的 self,实际上是对象本身,通过 self 可以访问内部成员self和:可以在函数定义时,也可以在函数调用时- 推荐使用
:
function _M:say()
print('hi ', self.name)
end
local obj = test:new()
obj:say()
- 相当于
obj.say(obj)闭包
World = {}
function World:say()
print("hi")
end
World.say2 = function (self)
print("hi2 " .. self.v)
end
World:say()
-- World:say2()
local clone = function (t)
local ins = {}
for key, value in pairs(t) do
ins[key] = value
end
return ins
end
local w = clone(World)
w.say()
-- w.say2()
World.new = function (v)
local self = clone(World)
self.v = v
self.bye = function ()
print("Bye " .. self.v)
end
return self
end
local w2 = World.new("world")
w2.say2(w2)
w2:say2()
w2.bye()