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查找 ...
随机推荐
- input file类型,文件类型的限制
直接限制input type='file'的文件类型限制,通过accept属性进行设定,多个类型用逗号分隔开,因为accept是html5的新特性,所以火狐和IE的支持就显得单薄了, 如:
- 转载:javascript面向对象编程:非构造函数的继承
一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...
- PHP基本知识收集
1.符号“@”的作用 @是可以屏蔽函数执行过程中遇到问题而产生的一些错误.警告信息,这样用户就看不到程序的出错信息.这样除了用户界面会友好一些外,更重要的是安全性,因为屏蔽了出错文件的路径等信息. 2 ...
- 引用CSS文件到html网页里方法
引用CSS文件到Html方法-css引入,css引用 使用不同的方法来引用css样式表,最终到达的效果相同,但是使用不同方法应用的css文件将影响到SEO及网页打开速度效率. html引用cs ...
- com组件接口
int main( int argc, char *argv[] ) { cout << "Initializing COM" << endl; ...
- mysql 无法启动1067
关键字:mysql无法启动办事,mysql卡死,InnoDB"" registration as a STORAGE ENGINE failed.Unknown/unsupport ...
- linux 一些命令
1.查看cpu个数 cat /proc/cpuinfo |grep "physical id" |sort | uniq |wc -l 2 2.查看cpu逻辑个数 cat /pro ...
- LInux软件的卸载和安装(转)
在linux环境中,尤其是cenos中安装过一些软件,一般是二进制安装与源码安装,现小结一下linux中的安装与卸载. 一.通常Linux应用软件的安装包有三种: 1) tar包,如software- ...
- VS2010 winform程序发布步骤
1.右键单击解决方案,点击“添加”---“新建项目”,如下图: 2.选择“其他项目类型”--“安装和部署”--“Visual Studio Installer”---"安装项目", ...
- 使用ContentProvider管理联系人------搜索联系人
此博客只实现了查询功能: import java.util.ArrayList; import android.os.Bundle;import android.provider.ContactsCo ...