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查找 ...
随机推荐
- javascript function new this
1. 首先,我们这里把function直接调用时将这个function当做方法来看待,而new function是将function当做类来看待 2. 当把function作为类来使用时,functi ...
- HTML:表格与表单
一.图片热点:规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- struts2视频学习笔记 28(OGNL表达式)
课时28 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语 ...
- vim 代码
vim函数跳转 时间:2014-05-07 14:02:12 阅读:40 ...
- asp.net core StaticFiles中间件修改wwwroot
new StaticFileOptions() { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentD ...
- [整][转]Invoke和BeginInvoke的使用
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate. 一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是do ...
- uva 10491
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 安装Adobe Dreamweaver CS6 免序列号 官方破解版
Adobe Dreamweaver CS6 免序列号 官方破解版 Adobe Dreamweaver CS6是世界顶级软件厂商Adobe推出的一套可视化的网页开发工具,Dreamweaver CS6最 ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- HDU 2795 单点更新,区间优先查找(想法)
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...