lua元表和元方法 《lua程序设计》 13章 读书笔记
lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表。lua在创建table时不会创建元表。
t = {}
print(getmetatable(t)) --显示过元表 此时是nil
--可以用setmetatable来设置或修改任何table的元表
t1 = {}
setmetatable(t,t1)
assert(getmetatable(t) == t1)
任何table可以作为任何值的元表,而一组相关的table可以共享一个通用的元表,此元表描述了一个共同的行为。一个tabel甚至可以作为它自己的元表,用于描述其特有行为。
在lua中,只能设置table的元表。要设置其它类型的元表,必须通过C代码来完成
print(getmetatable("hi")) --005DECD8 说明字符串有元表
print(getmetatable()) --number没有元表
13.1 算术类的元方法
Set = {} --集合
local mt = {} --集合元表
--根据参数列表中的值创建一个新的集合
function Set.new(l)
local set = {}
setmetatable(set,mt) --指定 table set的元表为mt
for k,v in ipairs(l) do
set[v] = true --注意,是拿索来当数据用的
end
return set
end
function Set.union(a,b)
local res = Set.new{}
for k,v in pairs(a) do res[k] = true end
for k,v in pairs(b) do res[k] = true end
return res
end
function Set.intersection(a,b)
local res = Set.new{}
for k,v in pairs(a) do
if b[k] then
res[k] = true
end
end
return res
end
function Set.tostring(set)
local l = {}
for k,v in pairs(set) do
l[#l + ] = k
end
return "{" .. table.concat(l,", ") .. "}"
end
function Set.print(s)
print(Set.tostring(s))
end
--将元方法加入元表
mt.__add = Set.union --指定加号为求并集的方法
mt.__mul = Set.intersection --指定乘号为交集的方法
s1 = Set.new{,,,,}
s2 = Set.new{,,,}
s3 = s1 + s2 --求并集
Set.print(s3) --输出 {11, 31, 66, 22, 33, 56, 44}
s4 = s1 * s2 --求交集
Set.print(s4) --输出 {31, 22}
13.2 关系类元方法
关系是指 __eq(等于)、__lt(小于)等
mt.__le = function(a,b)
for k in pairs(a) do
if not b[k] then return false end
end
return true
end mt.__lt = function(a,b)
return a<=b and not (b<=a)
end mt.__eq = function(a,b)
return a<=b and b<=a
end ss1 = Set.new{,}
ss2 = Set.new{,,}
print(ss1<=ss2) --true
print(ss1<ss2) --true
print(ss1>=ss1) --true
print(ss1>ss1) --false
print(ss1 == ss2*ss1) --true
13.3 库定义的元方法
tostring是一个典型的实例。它能将各种类型的值表示为简单的文本格式
print({}) ----table: 003ECEF0
函数总是调用tostring来格式化输出。当格式化任意值时,tostring会检测该值是否有一个 __tostring元方法。如果有,他就调用这个方法用来作为tostring的返回值
在集合实例中,我们定议了将任命表示为字符串的方法,我们可以设置元表的__tostring字段
mt.__tostring = Set.tostring
sstext = Set.new{,,}
print(sstext) --{55, 33, 6666}
假设想要保护集合的元表,使用户即不能看也不能修改集合的元表。那么就需要用到__metatable。当设置了该字段时,getmetatable就会返回这个字段的值,而setmetatable会引发一个错误
mt.__metatable = "not your business"
sstext1 = Set.new{}
print(getmetatable(sstext1)) --not your business
setmetatable(s1,{})
13.4 table 访问的元方法
13.4.1 __index元方法
当访问一个table中不存在的字段中时,如果这个字段不存在得到nil,但是如果这个table有一个元方法__index那么如果没有这个字段,就由这个元方法来提供结果
Window = {}
Window.prototype = {x=,y=,width = ,height = }
Window.mt = {}
function Window.new(o)
setmetatable(o,Window.mt)
return o
end
--现在定义一个元方法
Window.mt.__index = function(table,key)
return Window.prototype[key]
end
w = Window.new{x=,y=}
print(w.width) -- 100 window实际上没有width这个字段
__index元方法还可以是一个table
13.4.2 __newindex元方法
与__index不同的是__index是在查询的时候用的而_newindes是在更新的时候用的
13.4.3具有默认值的table
以下代码为table设置默认值
function setDefault(t,d)
local mt = {__index = function() return d end}
setmetatable(t,mt)
end
13.4.4 跟踪table的访问
__index和__newindex都是在table中没有所需的index才发挥作用。因为只有table保持空才能捕捉到所有对他的访问,为了监视一个table的所有访问就得为真正的 table 创建一个代理
t_src = {} --要跟踪的表
local _t = t_src
t = {} --创建代理
--创建元表
local mt = {
__index = function(t,k)
print("*access to element " .. tostring(k))
return _t[k]
end,
__newindex = function(t,k,v)
print("*update of element " .. tostring(k) .. " to " .. tostring(v))
_t[k] = v
end
}
setmetatable(t,mt)
t[] = "hello" -- *update of element 2 to hello
print(t[]) --*access to element 2
13.4.5 只读的table
只读table与上一节跟踪table类似,是通过__newindex来限制修改table内存
lua元表和元方法 《lua程序设计》 13章 读书笔记的更多相关文章
- Step By Step(Lua元表与元方法)
Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...
- lua元表与元方法
lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...
- lua——元表、元方法、继承
[元表] 元表中的键为事件(event),称值为元方法(metamethod). 通过函数getmetatable查询不论什么值的元表,通过函数setmetatable替换表的元表. setmetat ...
- lua 元表与元方法示例
-- 1.检查是否有元表local t = {1, 2}print(getmetatable(t)) -- nilprint("----------------------" ...
- 《WCF全面解析》-上册 1-3章 读书笔记
第一章.WCF简介 ESB全称为Enterprise Service Bus,即企业服务总线.把所有的服务统筹到一个总线里面请求和分发,方便管理. WCF(Windows Communication ...
- lua编程之元表与元方法
一. 前言 lua是一种非常轻量的动态类型语言,在1993年由由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo等人 ...
- Lua 学习笔记(十一)元表与元方法
在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...
- lua中 table 元表中元方法的重构实现
转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...
随机推荐
- Echart多图联动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- Python Twisted介绍
原文链接:http://www.aosabook.org/en/twisted.html 作者:Jessica McKellar Twisted是用Python实现的基于事件驱动的网络引擎框架.Twi ...
- ie8解决F12问题
工作中,突然电脑上的ie8按F12掉不出来了,一直显示最小化.于是在网上找了很多方法,按这种方法可以解决问题. 1.cmd+r,输入regedit,调出 注册表编辑器. 2.HKEY_CURRENT_ ...
- 用户列表-投资记录sql
--普通标.定向标.新手标.老互融计划-投资记录表select bid.borrow_id, (select yyb.borrow_valid_time from YYD_Borrow_BorrowI ...
- call,apply,bind函数
一.call函数 a.call(b); 简单的理解:把a对象的方法应用到b对象上(a里如果有this,会指向b) call()的用法:用在函数上面 var Dog=function(){ this.n ...
- 用while循环语句计算1!+2!+……20!之和
package nothh; public class mmm { public static void main(String[] args) { // TODO Auto-generated me ...
- 微信支付调用JSAPI缺少参数:timeStamp
一般是安卓没问题,苹果会出现这样的问题,弹出下面这样的提示,如果你也是这样,那就恭喜你,现在,你找到解决的方法了 请看红色框框的timeStamp(图片有点小,可以鼠标右键打开图片 查看) 请注意,这 ...
- 在shell脚本中使用函数
转载请标明:http://www.cnblogs.com/winifred-tang94/ 对于在脚本中重复使用的功能模块,可以封装成为函数. shell脚本中函数的定义可以使用如下两种方式: a. ...
- 计算文字的高度和宽度--以微博会话界面中用户名(userName)为例
所用方法 // NOTE: All of the following methods will default to drawing on a baseline, limiting drawing t ...
- python解无忧公主的数学时间编程题001.py
python解无忧公主的数学时间编程题001.py """ python解无忧公主的数学时间编程题001.py http://mp.weixin.qq.com/s?__b ...