Lua Metatable

作者: 小城大麦 | 来源:发表于2016-08-16 17:30 被阅读25次

算数运算和逻辑运算(类似操作符重载)

+-*/ __add __sub __mul __div
% ^ __mod,__pow
== < > __eq __lt __le

local obj = {1}
m = getmetatable(obj)
print m -- nil
m = {__add = function(a,b) return {a,b} end}
setmetatable(obj,m)
local obj2 = {2}
setmetatable(obj2,m)
local ret = obj +_ obj2 -- {{1},{2}}

库定义的元方法

__tostring 格式输出
local a = {}
local mt = {__tostring = function(t) return "table_a" end}
setmetatable(a,mt)
print() -- print(tostring(a)) == __tostring(a) table_a

__metatable:如果有值,getmetatable返回此值,且
不能调用setmetatble修改

table访问的元方法
__index 如果访问table中字段不存在,且存在__index的元方法,那么调用__index [__index(table,key)]
使用rawget(table,key)方法可以绕过这个机制

local obj = {name="obj"}
local mt = {
  __index = function(t,k) return "test" end
}
setmetatable(obj,mt)
-- any not exists key in obj will return test
print(obj.name) -- "obj"
print(obj.any) -- "test"

__newindex 如果更新的字段在table不存在,且存在__newindex元方法,那么将调用__newindex方法[__newindex(table,key,value)]
使用rawset(table,key,value)方法可以绕过这个机制

obj = {name="obj"}
mt = {
    -- we cannot use t[k]=v this will recursive invoke __newindex
  __newindex = function(t,k,v) v = "test_"..tostring(v) rawset(t,k,v) end
}

setmetatable(obj,mt)
print(obj.name) -- "obj"
obj.name = "hello" print(obj.name) -- "hello"
obj.any = "work" print(obj.any) -- "test_work"
obj.any = "any" print(obj.any) -- "any" because any is exists in table

应用代理访问

function create_proxy(target)
    local _t = target
    local t = {}
    local mt = {
        __index = function(t,k) print("access to element "..tostring(k)) return _t[k] end,
        __newindex = function(t,k,v) print("update element "..tostring(k)) _t[k] = v end
    }
    setmetatable(t,mt)
    return t;
end
target = {}
proxy = create_proxy(target)
proxy.price = 10.0
print(proxy.price)

get/set一种简单实现

local Book = {}
function Book.new()
  local accessor = {
    name = {
      value = 0,
      get = function() return value end,
      set = function(new_value) value = new_value end
    }
  }
  local meta = {
    __index = function(_,key)
        return accessor[key].get();
      end,
    __newindex = function(_,key,value)
          accessor[key].set(value)
      end
  }
  local o = {}
  setmetatable(o,meta);
  return o
end

local mybook = Book.new()
mybook.name = "bookname_100"
print(mybook.name)

readOnly

function readOnly(t)
    local proxy = {}
    local mt = {
        __index = t,
        __newindex = function(t,k,v) error("attempt to update a readonly table",2) end
    }
    setmetatable(proxy,mt)
    return proxy
end

弱应用与垃圾回收
Lua中table的弱引用有三种Key弱引用,Value弱应用,Key,Value同时为弱引用
对应字符串,其本身是一个值,不是对象,并不一定会被回收。

定义一个弱引用 __mode元字段

a = {}
mt = {__mode = "k"}
setmetatable(a,mt) -- a为key的弱引用
key = {}
a[key] = 1
key={} //pre key is nil,will be collected as garbage
a[key] = 2
collectgarbage()
for k,v in pairs(a) do print(v) end -->2

相关文章

  • Lua 元表元方法(Metatables and Metamet

    1、Every value in Lua can have a metatable. This metatable...

  • lua元表

    1、Lua 元表(Metatable) setmetatable(table,metatable): 对指定tab...

  • Lua 元表(Metatable)

    学习网站Lua 元表(Metatable)

  • Lua Metatable

    算数运算和逻辑运算(类似操作符重载) 库定义的元方法 table访问的元方法__index 如果访问table中字...

  • Lua----元表(Metatable)

    什么是元表 This metatable is an ordinary Lua table that define...

  • Lua学习

    Lua 学习 元表 setmetatable(table,metatable): 对指定table设置元表(met...

  • lua元表(Metatable)

    Lua 提供的元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。 __inde...

  • Lua元表Metatable

    1. 元表的含义 元表是带有索引集合的表,它可以改变被附加的表的行为 2. 算术类的元方法 下面是我们为我们tab...

  • Lua 元表(Metatable)

    在 Lua table 中我们可以访问对应的key来得到value值,但是却无法对两个 table 进行操作。 因...

  • lua metatable __nexindex方法

    __index元方法是访问,如果表中没有就会进元方法查找(如果有元表的话),如果元方法是表,返回元表的元素;如果元...

网友评论

    本文标题:Lua Metatable

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