lua-openresty (3)

元表(类似操作符重载)

OpenResty 最佳实践

Lua 提供的所有操作符都可以被重载:

元方法 含义
"__add" + 操作
"__sub" - 操作 其行为类似于 "add" 操作
"__mul" * 操作 其行为类似于 "add" 操作
"__div" / 操作 其行为类似于 "add" 操作
"__mod" % 操作 其行为类似于 "add" 操作
"__pow" ^ (幂)操作 其行为类似于 "add" 操作
"__unm" 一元 - 操作
"__concat" .. (字符串连接)操作
"__len" # 操作
"__eq" == 操作 函数 getcomphandler 定义了 Lua 怎样选择一个处理器来作比较操作 仅在两个对象类型相同且有对应操作相同的元方法时才起效
"__lt" < 操作
"__le" <= 操作

除了操作符之外,如下元方法也可以被重载,下面会依次解释使用方法:

元方法 含义
"__index" 取下标操作用于访问 table[key]
"__newindex" 赋值给指定下标 table[key] = value
"__tostring" 转换成字符串
"__call" 当 Lua 调用一个值时调用
"__mode" 用于弱表(week table)
"__metatable" 用于保护metatable不被访问

__index 元方法

下面的例子中,我们实现了在表中查找键不存在时转而在元表中查找该键的功能:

mytable = setmetatable({key1 = "value1"},   --原始表
  {__index = function(self, key)            --重载函数
    if key == "key2" then
      return "metatablevalue"
    end
  end
})

print(mytable.key1,mytable.key2)  --> output:value1 metatablevalue
关于 __index 元方法,有很多比较高阶的技巧,例如:__index 的元方法不需要非是一个函数,他也可以是一个表。
t = setmetatable({[1] = "hello"}, {__index = {[2] = "world"}})
print(t[1], t[2])   -->hello world
__call 元方法

__call 元方法的功能类似于 C++ 中的仿函数,使得普通的表也可以被调用。

functor = {}
function func1(self, arg)
  print ("called from", arg)
end

setmetatable(functor, {__call = func1})

functor("functor")  --> called from functor
print(functor)      --> output:0x00076fc8 (后面这串数字可能不一样)

面向对象编程


account.lua

local _M = {}

local mt = { __index = _M }

function _M.deposit (self, v)
    self.balance = self.balance + v
end

function _M.withdraw (self, v)
    if self.balance > v then
        self.balance = self.balance - v
    else
        error("insufficient funds")
    end
end

function _M.new (self, balance)
    balance = balance or 0
    return setmetatable({balance = balance}, mt)
end

return _M

引用代码示例:

local account = require("account")

local a = account:new()
a:deposit(100)

local b = account:new()
b:deposit(50)

print(a.balance)  --> output: 100
print(b.balance)  --> output: 50
继承
判断为空

因此,我们要判断一个 table 是否为 {},不能采用 #table == 0 的方式来判断。可以用下面这样的方法来判断:

 function isTableEmpty(t)
    return t == nil or next(t) == nil
end

你可能感兴趣的:(lua-openresty (3))