- Lua 教程
- Lua - 首页
- Lua 基础
- Lua - 概述
- Lua - 环境
- Lua - 基本语法
- Lua - 注释
- Lua - 打印 Hello World
- Lua - 变量
- Lua - 数据类型
- Lua - 运算符
- Lua - 循环
- Lua - 决策制定
- Lua - 函数
- Lua - 日期和时间
- Lua 数组
- Lua - 数组
- Lua - 多维数组
- Lua - 数组长度
- Lua - 遍历数组
- Lua 迭代器
- Lua - 迭代器
- Lua 列表
- Lua - 在列表中搜索
- Lua 模块
- Lua - 模块
- Lua - 命名空间
- Lua 元表
- Lua - 元表
- Lua 协程
- Lua - 协程
- Lua 文件处理
- Lua - 文件 I/O
- Lua 库
- Lua - 标准库
- Lua - 数学库
- Lua - 操作系统功能
- Lua 有用资源
- Lua - 快速指南
- Lua - 有用资源
- Lua - 讨论
Lua - 元表
元表是一个表,它通过一组键和相关的元方法来帮助修改与其关联的表的行为。这些元方法是强大的 Lua 功能,可以实现以下功能:
更改/添加表格上运算符的功能。
当键在表中不可用时,使用元表中的 __index 来查找元表。
在处理元表时,有两种重要的方法:
setmetatable(table,metatable) - 此方法用于为表设置元表。
getmetatable(table) - 此方法用于获取表的元表。
让我们首先了解如何将一个表设置为另一个表的元表。如下所示。
mytable = {} mymetatable = {} setmetatable(mytable,mymetatable)
以上代码可以表示为一行,如下所示。
mytable = setmetatable({},{})
示例 - _index
下面是一个简单的元表示例,用于在表中找不到时查找元表。
main.lua
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return nil end end }) print(mytable.key1, mytable.key2)
输出
运行以上程序时,将获得以下输出。
value1 metatablevalue
让我们分步解释以上示例中发生的情况。
这里的 mytable 表是 {key1 = "value1"}。
为 mytable 设置了元表,其中包含 __index 的函数,我们将其称为元方法。
元方法的工作很简单,查找索引 "key2",如果找到,则返回 "metatablevalue",否则返回 mytable 对应索引的值。
我们可以将以上程序简化为如下所示。
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)
示例 - __newindex
当我们在元表中添加 __newindex 时,如果表中不存在键,则新键的行为将由元方法定义。下面是一个简单的示例,在主表中不存在索引时设置元表的索引。
main.lua
mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable }) print(mytable.key1) mytable.newkey = "new value 2" print(mytable.newkey,mymetatable.newkey) mytable.key1 = "new value 1" print(mytable.key1,mymetatable.newkey1)
输出
运行以上程序时,将获得以下输出。
value1 nil new value 2 new value 1 nil
您可以在以上程序中看到,如果键存在于主表中,则它只更新它。当键在 maintable 中不可用时,它会将该键添加到元表中。
示例 - 更新表
另一个使用 rawset 函数更新同一表的示例如下所示。
main.lua
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2)
输出
运行以上程序时,将获得以下输出。
new value "4"
rawset 在不使用元表的 __newindex 的情况下设置值。类似地,rawget 在不使用 __index 的情况下获取值。
示例 - 向表添加运算符行为
下面是一个简单的示例,使用 + 运算符组合两个表:
main.lua
mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table.maxn(newtable) do table.insert(mytable, table.maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print(k,v) end
输出
运行以上程序时,将获得以下输出。
1 1 2 2 3 3 4 4 5 5 6 6
元表中包含 __add 键,以添加 + 运算符的行为。键和对应运算符的表如下所示。
序号 | 模式和描述 |
---|---|
1 | __add 更改 + 运算符的行为。 |
2 | __sub 更改 - 运算符的行为。 |
3 | __mul 更改 * 运算符的行为。 |
4 | __div 更改 / 运算符的行为。 |
5 | __mod 更改 % 运算符的行为。 |
6 | __unm 更改 - 运算符的行为。 |
7 | __concat 更改 .. 运算符的行为。 |
8 | __eq 更改 == 运算符的行为。 |
9 | __lt 更改 < 运算符的行为。 |
10 | __le 更改 <= 运算符的行为。 |
示例 - __call
使用 __call 语句添加方法调用的行为。一个简单的示例,返回主表中值与传递表的总和。
main.lua
mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, table.maxn(mytable) do sum = sum + mytable[i] end for i = 1, table.maxn(newtable) do sum = sum + newtable[i] end return sum end }) newtable = {10,20,30} print(mytable(newtable))
输出
运行以上程序时,将获得以下输出。
70
示例 - __tostring
要更改 print 语句的行为,我们可以使用 __tostring 元方法。下面是一个简单的示例。
main.lua
mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "The sum of values in the table is " .. sum end }) print(mytable)
输出
运行以上程序时,将获得以下输出。
The sum of values in the table is 60
如果您完全了解元表的功能,那么您可以执行许多操作,而无需使用它,这些操作将非常复杂。因此,尝试更多地使用元表以及元表中提供的不同选项,如示例中所解释的那样,并创建您自己的示例。