元表和元方法

简介: 元表和元方法

通常, Lua 语言中的每种类型的值都有一套可预见的操作集合。例如,我们可以将数字相加,可以连接字符串,可以在表中插入键值对等。但是,我们无法将两个表相加,无法对函数作比较,也无法调用一个字符串,除非使用元表


元表可以修改一个值在面对一个未知操作时的行为。例如,假设 ab 都是表,那么可以通过元表定义 Lua 语言如何计算表达式 a + b 。当 Lua 语言试图将两个表相加时,它会先检查两者之一是否有元表且该元表中是否有 _add 字段。如果 Lua 语言找到了该字段,就调用该字段对应的值,即所谓元方法(是一个函数)。


可以认为,元表是面向对象领域中的受限制类,像类一样,元表定义的是实例的行为。不过,由于元表只能给出预先定义的操作集合的行为,所以元表比类更受限;同时,元表不支持继承。不过尽管如此,我们依然可以基于元表构建一个相对完整的类系统;


Lua 语言中的每一个值都可以有元表。每一个表和用户数据类型都具有各自独立的元表,而其他类型的值则共享对应类型所属的同一个元表。 Lua 语言在创建新表时不带元表:

t = {}
print(getmetatable(t)) --> nil


可以使用函数 setmetatable 来设置或修改任意表的元表:

t1 = {}
setmetatable(t, t1)
print(getmetatable(t) == t1) --> true


Lua 语言中,我们只能为表设置元表,如果要为其他类型的值设置元表,则必须通过 C 代码或调用库完成(该限制存在的主要原因是为了防止过度使用对某种类型的所有值生效的元表。 Lua 语言老版本中的经验表明,这样的全局设置经常导致不可重用的代码)。字符串标准库为所有的字符串都设置了同一个元表,而其他类型在默认情况下都没有元表:

print(getmetatable("hi"))       --> table 0x80772e0
print(getmetatable("hello"))    --> table 0x80772e0
print(getmetatable(10))         --> nil
print(getmetatable(print))      --> nil


一个表可以称为任意值的元表,一组相关的表也可以共享一个描述了他们共同行为的通用元表,一个表还可以成为它自己的元表,用于描述其自身特有的行为。总之,任何配置都是合法的。

目录
相关文章
|
11月前
|
索引
lua元表、元方法
lua元表、元方法
70 0
|
5月前
|
编译器 C++
01QT元对象系统
一、元对象系统    元对象系统是一个基于标准C++的扩展,为Qt提供了信号与槽机制、实时类型信息、动态属性系统。 元对象系统的三个基本条件:
45 0
|
2月前
|
索引
Lua语法(三)——元表与元方法
Lua语法(三)——元表与元方法
31 0
|
5月前
|
存储 编译器 C++
【Qt 元对象系统 02】深入探索Qt的元对象编译器:从原理到实践
【Qt 元对象系统 02】深入探索Qt的元对象编译器:从原理到实践
319 0
|
5月前
|
Kubernetes NoSQL Java
Lua 元表及常见元方法
Lua 元表及常见元方法
|
Serverless C++
【C++之静态数据成员和静态成员函数】计算商品总销售款和平均售价
【C++之静态数据成员和静态成员函数】计算商品总销售款和平均售价
|
缓存
__index 元方法
__index 元方法
90 1
装饰模式实例复杂的奖金计算
装饰模式实例复杂的奖金计算
115 0
装饰模式实例复杂的奖金计算
原型模式实例订单处理系统
原型模式实例订单处理系统
114 0
原型模式实例订单处理系统