美文网首页
lua-openresty (3)

lua-openresty (3)

作者: scriptllh | 来源:发表于2018-05-08 18:07 被阅读0次

    元表(类似操作符重载)

    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)

          本文链接:https://www.haomeiwen.com/subject/gzpwrftx.html