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(10))  --number没有元表

13.1  算术类的元方法

Set = {}  --集合local mt = {}  --集合元表--根据参数列表中的值创建一个新的集合
function Set.new(l)local set = {}setmetatable(set,mt)  --指定 table set的元表为mtfor k,v in ipairs(l) doset[v] = true    --注意,是拿索来当数据用的endreturn set
end
function Set.union(a,b)local res = Set.new{}for k,v in pairs(a) do res[k] = true endfor k,v in pairs(b) do res[k] = true endreturn res
endfunction Set.intersection(a,b)local res = Set.new{}for k,v in pairs(a) doif b[k] thenres[k] = trueendendreturn res
endfunction Set.tostring(set)local l = {}for k,v in pairs(set) dol[#l + 1] = kendreturn "{" .. table.concat(l,", ") .. "}"
endfunction Set.print(s)print(Set.tostring(s))
end--将元方法加入元表
mt.__add = Set.union   --指定加号为求并集的方法
mt.__mul = Set.intersection  --指定乘号为交集的方法

s1 = Set.new{11,22,31,44,56}
s2 = Set.new{66,33,22,31}
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) doif not b[k] then  return false endendreturn true
endmt.__lt = function(a,b)return a<=b and not (b<=a)
endmt.__eq = function(a,b)return a<=b and b<=a
endss1 = Set.new{2,4}
ss2 = Set.new{4,10,2}
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{33,55,6666}
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=0,y=0,width = 100,height = 100}
Window.mt = {}function Window.new(o)setmetatable(o,Window.mt)return o
end--现在定义一个元方法
Window.mt.__index = function(table,key)return Window.prototype[key]
endw = Window.new{x=10,y=20}
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_srct = {} --创建代理--创建元表
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] = vend
}
setmetatable(t,mt)t[2]  = "hello"  -- *update of element 2 to hello
print(t[2])  --*access to element 2

13.4.5 只读的table

只读table与上一节跟踪table类似,是通过__newindex来限制修改table内存

出处:http://www.cnblogs.com/zhangdongsheng/
作者:张东升

lua元表和元方法 《lua程序设计》 13章 读书笔记相关推荐

  1. 游戏设计艺术 第2版 第13章 读书笔记

    平衡一个游戏,就是调整游戏的各种元素,直到这些元素传达了游戏设计师想要的体验. 平衡游戏涉及到一些简单数学,是游戏设计中最艺术的一块. 平衡游戏的本质是了解游戏中各种元素之间的细微差别,并且清楚调整哪 ...

  2. Lua程序设计 | 模块和包、泛型迭代器和for、元表和元方法

    From<Programming in Lua> by Roberto Ierusalimschy 文章目录 模块和包 函数 require 模块重命名 搜索路径 搜索器 Lua语言中编写 ...

  3. Lua 学习元表,元方法

    前言 Lua本身没有面向对象的思想,但是可以根据表.元表.元方法来靠近它 一.元表与元方法的概念 Lua中每个值都可具有元表.元表是普通的Lua表,定义了原始值在某些特定操作下 的行为.例如,当tab ...

  4. Lua元表(__index方法个人理解)

    什么是Lua元表: 原表可理解为"一个方法表(类似函数表)",里面包含了一些解决方案.当一个table设置元表之后,相当于关联了这个方法表 setmetatable(table,m ...

  5. 计算机网络 自顶向下方法 第七版中文 读书笔记 目录

    计算机网络 自顶向下方法 第七版中文 读书笔记 目录 计算机网络 自顶向下方法 第七版中文 读书笔记 目录 第 1 章 计算机网络和因特网 第 2 章 应用层 第 3 章 运输层 第 4 章 网络层 ...

  6. Lua语言编程学习之路02----第13章 元表与元方法

    前言   在Lua中我们无法直接对两个table进行相加,无法对函数进行比较,也无法调用一个函数. 于是Lua可以通过修改一个值的行为,使其在面对一个非预定义的操作时执行一个自己实现的操作.比如两个t ...

  7. lua学习笔记之元表和元方法

    元表允许当遇到未知操作时,改变值的行为.例如,使用元表,可以定义表a与表b的关系运算a+b.当lua尝试两个表相加时,会检查是否其中一个有元表并且元表是否有__add字段. 元表在面向对象的术语中是一 ...

  8. 《Python程序设计教程》读书笔记

    第一章 程序设计概述 1.1 程序设计基础知识 算法+数据结构=程序 程序设计四步骤:1分析问题,确定数学模型或方法2设计算法,画出流程图3选择编程工具,按算法编写程序4调试程序,分析输出结果 算法的 ...

  9. Thinking in java 第13章 字符串 笔记+习题

    Thinking in java 第13章 字符串 学习目录 13.1 不可变String 13.2 重载"+"与StringBuilder 1. 用于String的"+ ...

最新文章

  1. [WTL] STLport安装指南
  2. 电子计算机工程学,计算机工程
  3. [armv9]-ARMV9 CCA 机密计算简介
  4. Android 监听Home键
  5. [Unity3d]多个摄像机叠加效果
  6. java流与文件——ZIP文档
  7. hibernate mysql 时间_使用Hibernate和MySQL创建时间戳和最后更新时间戳
  8. 小鹏汽车第10000辆P7下线
  9. C++实现的Miller-Rabin素性测试程序
  10. Compiere 开源CRM的比较选择
  11. 全网首发:WORD你光标乱跳什么?
  12. kylin安装以及遇见到的一些问题和解决方法
  13. 公司总经理KPI考核指标
  14. 老男孩老师的博客地址
  15. 软件测试之项目实战,必须知道的事与测试面试项目测试流程......
  16. java spring源码_剑指Java自研框架,决胜Spring源码
  17. 刘克亚励志演讲(清晨/夜晚)
  18. 报告论文:手写数字识别
  19. 手机计算机怎么恢复出厂设置密码,手机开机密码忘了怎么解锁
  20. c#word文档输出

热门文章

  1. 树结构练习——排序二叉树的中序遍历(二叉搜索树)
  2. 双击打开excel时提示:向程序发送命令时出现问题
  3. 客户网页WIZnet无线解决方案 之 太阳能逆变器
  4. 32位处理器的寄存器介绍
  5. 实战操作主机角色转移,Active Directory系列之十
  6. 解Bug之路-Druid的Bug
  7. Navicat Premium 11.1.9在Linux系统下的安装
  8. 《Effect Java》学习笔记1———创建和销毁对象
  9. 程序员的“认知失调”
  10. [译]SSAS下玩转PowerShell(三)