Bootstrap

lua 对象编程解读

假设要实现汽车类,一个标准的 lua 面向对象实现方式如下:

car.lua

local _car = {}

local mt = { __index = _car }

-- 对象初始化方法,可以传入初始化参数 opts
function _car:new(opts)
	local opts = opts or {}

  
  local mt = { __index = self }
  
  -- 初始化方法返回一个 table,该 table 包含汽车类的属性
  -- 并且为该 table 设置元表, 该元表的 __index 方法为汽车类 __car
  -- 这样返回的 table 就拥有了汽车类(__car) 的操作方法
  return setmetatable({
    color = opts.color or 'red',
    brand = opts.brand or 'audi'
  }, mt)
end

function _car:setColor(color)
  self.color = color  
end

function _car:getColor()
  return self.color
end

return _car

这里主要用到 lua 中的元表概念。每个 table 类型的数据都可以通过 setmetatable 方法设置元表。元表主要通过元方法修改 table 数据的行为。这里用到的是 __index 这个元方法。

例:

local a = {}
local b = {
  name = "zhangsan"
}

-- mt 作为 a 的元表, 元表 mt 的元方法设置为变量 b
local mt = { __index = b }
setmetatable(a, mt)

print(a.name)

如上例子中,如果要获取表 a 的 name 字段,a 本身是没有 name 字段的,就会搜索其元表中的 __index 元方法,如果 __index 的值为 table,就会从该 table 中搜索 name 字段,如果有 name 字段就获取其值,否则返回 nil

当然,__index 元方法也可以是一个函数,这样当获取 a 中不存在的字段时,就会调用该方法,并返回该方法的返回值,如果定义了的话。