库定义相关的元方法

简介: 库定义相关的元方法

到目前为止,我们见过的所有元方法针对的都是核心 Lua 语言。 Lua 语言虚拟机会检测一个操作中涉及的值是否有存在的对应元方法的元表。不过,由于元表是一个普通的表,所以任何人都可以使用他们。因此,程序库在元表中定义和使用他们自己的字段也是一种常见的实践。


函数 tostring 就是一个典型的例子。函数 tostring 能将表表示为一种简单的文本格式:

print({})   --> table: 0x8062ac0


函数 print 总是调用 tostring 来进行格式化输出。不过,当对值进行格式化时,函数 tostring 会首先检查值是否有一个元方法 __tostring 。如果有,函数 tostring 就会调用这个元方法来完成工作,将对象作为参数传给该函数,然后把元方法的返回值作为函数 tostring 的返回值。


在之前集合的示例中,我们已经定义了一个将集合表示为字符串的函数。因此,只需要在元表中设置 __tostring 字段:

mt.__tostring = Set.tostring


之后,当一个集合作为参数调用函数 print 时, print 就会调用函数 tostringtostring 又会调用 Set.tostring

s1 = Set.new{10, 4, 5}
print(s1) --> {4, 5, 10}


函数 setmetatablegetmetatable 也用到了元方法,用于保护元表。假设想要保护我们的集合,就要使用户既不能看到也不能修改集合的元表。如果在元表中设置 __metatable 字段,那么 getmetatable 会返回这个字段的值,而 setmetatable 则会引发一个错误:

mt.__metatable = "not your business"
s1 = Set.new{}
print(getmetatable(s1))   --> not your business
setmetatable(s1, {})
  stdin:1: cannot change protected metatable


Lua 5.2 开始,函数 pairs 也有了对应的元方法,因此我们可以修改表被遍历的方式和为非表的对象增加遍历行为。当一个对象拥有 __pairs 元方法时, pairs 会调用这个元方法来完成遍历。

目录
相关文章
|
7月前
|
设计模式 缓存 编译器
【C++ 元对象系统03】深入探索Qt反射:从原理到实践
【C++ 元对象系统03】深入探索Qt反射:从原理到实践
288 5
|
7月前
|
编译器 C++
01QT元对象系统
一、元对象系统    元对象系统是一个基于标准C++的扩展,为Qt提供了信号与槽机制、实时类型信息、动态属性系统。 元对象系统的三个基本条件:
52 0
|
7月前
|
缓存 编译器 程序员
【Qt 元对象系统04】 深入浅出Qt的QMetaObject:探索元对象的魔法
【Qt 元对象系统04】 深入浅出Qt的QMetaObject:探索元对象的魔法
480 0
|
6月前
|
数据安全/隐私保护 C++
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
C++ 中的类是一种用户定义的数据类型,用于表示具有相似特征和行为的对象的模板。
|
7月前
|
存储 C++
【C++模板】模板实现通用的数组
【C++模板】模板实现通用的数组
|
7月前
|
自然语言处理 编译器 程序员
【Qt底层之 元对象的编译】Qt 元对象系统及其编译流程解析
【Qt底层之 元对象的编译】Qt 元对象系统及其编译流程解析
355 4
|
7月前
|
存储 编译器 C++
【Qt 元对象系统 02】深入探索Qt的元对象编译器:从原理到实践
【Qt 元对象系统 02】深入探索Qt的元对象编译器:从原理到实践
419 0
|
Java 容器
Java容器类型以及使用方法(1)
Java容器类型以及使用方法(1)
|
Scala 开发者
包对象注意事项和细节说明|学习笔记
快速学习包对象注意事项和细节说明。
包对象注意事项和细节说明|学习笔记
|
小程序 Java
Java——静态字段和实例字段的初始化说明(概念理解+应用举例)
Java——静态字段和实例字段的初始化说明(概念理解+应用举例)
Java——静态字段和实例字段的初始化说明(概念理解+应用举例)