Lua基础:Metatables and Metamethods

算术运算的 Metamethods:

  1. Set={}
  2.  
  3. function Set.union(a,b)
  4.     local res=Set.new{}
  5.     for k in pairs(a) do res[k]=true end
  6.     for k in pairs(b) do res[k]=true end
  7.     return res
  8. end
  9.  
  10. function Set.intersection(a,b)
  11.     local res=Set.new{}
  12.     for k in pairs(a) do
  13.         res[k]=b[k]
  14.     end
  15.     return res
  16. end
  17.  
  18. function Set.tostring(set)
  19.     local s="{"
  20.     local sep=""
  21.     for e in pairs(set) do
  22.         s=s .. sep .. e
  23.         sep=", "
  24.     end
  25.     return s .. "}"
  26. end
  27.  
  28. function Set.print(s)
  29.     print(Set.tostring(s))
  30. end
  31.  
  32. Set.mt={}
  33.  
  34. function Set.new(t)
  35.     local set={}
  36.     setmetatable(set,Set.mt)
  37.     for _,l in ipairs(t) do set[l]=true end
  38.         return set
  39. end
  40.  
  41. s1=Set.new{10,20,30,50}
  42. s2=Set.new{30,1}
  43. print(getmetatable(s1))
  44. print(getmetatable(s2))
  45.  
  46. Set.mt.__add = Set.union
  47. s3=s1+s2
  48. Set.print(s3)
  49. Set.mt.__mul = Set.intersection
  50. Set.print((s1+s2)*s1)

关系运算的 Metamethods:

  1. Set.mt={}
  2.  
  3. function Set.new(t)
  4.     local set={}
  5.     setmetatable(set,Set.mt)
  6.     for _,l in ipairs(t) do set[l]=true end
  7.         return set
  8. end
  9.  
  10. Set.mt.__add = Set.union
  11. Set.mt.__mul = Set.intersection
  12.  
  13. Set.mt.__le = function (a,b)
  14.     for k in pairs(a) do
  15.      if not b[k] then return false end
  16.     end
  17.      return true
  18. end
  19.  
  20. Set.mt.__lt = function (a,b)
  21.     return a <= b and not (b <= a)
  22. end
  23.  
  24. Set.mt.__eq = function (a,b)
  25.     return a <= b and b <= a
  26. end
  27.  
  28. s1=Set.new{2,4}
  29. s2=Set.new{4,10,2}
  30.  
  31. print(s1<=s2)
  32. print(s1<s2)
  33. print(s1>=s1)
  34. print(s1>s1)
  35. print(s1==s2*s1)

库定义的 Metamethods:

  1. print({})
  2.  
  3. Set.mt.__tostring = Set.tostring
  4. s1=Set.new{10,4,5}
  5. print(s1)
  6.  
  7. Set.mt.__metatable = "not your business"
  8. s1 = Set.new{}
  9. print(getmetatable(s1))

表相关的 Metamethods:

The __index Metamethod:返回结果

  1. Window={}
  2.  
  3. Window.prototype={x=0,y=0,width=100,height=100,}
  4.  
  5. Window.mt={}
  6.  
  7. function Window.new(o)
  8.     setmetatable(o,Window.mt)
  9.     return o
  10. end
  11.  
  12. Window.mt.__index = function (table, key)
  13.     return Window.prototype[key]
  14. end
  15.  
  16. w=Window.new{x=10,y=20}
  17. print(w.width)

The __newindex Metamethod:更新表

设置默认值:

  1. function setDefault(t,d)
  2.     local mt={__index =function() return d end}
  3.     setmetatable(t,mt)
  4. end
  5. tab={x=10,y=20}
  6. print(tab.x,tab.y,tab.z)
  7. print()
  8. setDefault(tab,0)    --设置默认值
  9. print(tab.x,tab.y,tab.z)

监控表:

  1. t = {}  --原始表
  2.  
  3. local _t = t
  4.  
  5. t = {}  --代理
  6.  
  7. local mt = {   --表
  8.      __index = function (t,k)
  9.      print("*access to element " ..  tostring(k))
  10.      return _t[k]            --原始表数据
  11.      end,
  12.      __newindex = function (t,k,v)
  13.      print("*update of element " .. tostring(k) .. " to " .. tostring(v))
  14.      _t[k] = v                 --更新后的数据
  15.      end
  16. }
  17.  
  18. setmetatable(t, mt)
  19.  
  20. t[2]='hello'
  21. print(t[2])

只读表:

  1. function readOnly(t)
  2.     local proxy={}
  3.     local mt = {               -- create metatable
  4.          __index = t,
  5.          __newindex = function (t,k,v)
  6.              error("attempt to update a read-only table", 2)
  7.          end
  8.     }
  9.     setmetatable(proxy,mt)
  10.     return proxy
  11. end
  12.  
  13. days=readOnly{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
  14. print(days[1])
  15. --days[2]="Noday"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值