Lua 元表和元方法

元表(Metatable)和元方法(Metamethod)是Lua中实现面向对象编程、操作符重载和自定义行为的重要机制。

元表

元表是一个普通的Lua表,可以附加到另一个表上,用于定义或修改该表的行为。每个表都可以有自己的元表。

|-------------------------------|-------------------|
| setmetatable(tab,metatab) | 将metatab设置为tab的元表 |
| getmetatable(tab) | 获取表tab的元表 |

Lua 复制代码
local t = {}
local mt = {}  -- 元表

-- 设置元表
setmetatable(t, mt)

-- 获取元表
local mt_of_t = getmetatable(t)

元方法

元方法是定义在元表中的特殊键,当表参与特定操作时会被调用。

运算相关元方法

Lua 复制代码
local Calculate = {}

local data1 = {number = 2}
local data2 = {number = 4}

setmetatable(data1,Calculate)
setmetatable(data2,Calculate)

--加
Calculate.__add = function(a,b)
   return a.number+b.number
end
print(data1 + data2)

--减
Calculate.__sub = function(a,b)
   return a.number-b.number
end
print(data1 - data2)

--乘
Calculate.__mul = function(a,b)
   return a.number*b.number
end
print(data1 * data2)

--除
Calculate.__div = function(a,b)
   return a.number/b.number
end
print(data1 / data2)

--取余
Calculate.__mod = function(a,b)
   return a.number%b.number
end
print(data1 % data2)

--等于判断
Calculate.__eq = function(a,b)
   return a.number == b.number
end
print(data1 == data2)

--连接符
Calculate.__concat = function(a,b)
   return a.number .. b.number
end
print(data1..data2)

--小于号
Calculate.__lt = function(a,b)
   return a.number < b.number
end
print(data1<data2)

--小于或等于
Calculate.__le = function(a,b)
   return a.number <= b.number
end
print(data1 <= data2)

--幂运算
Calculate.__pow = function(a,b)
   return a.number ^ b.number
end
print(data1 ^ data2)

--负数
Calculate.__unm = function(a)
   return -a.number
end

print(-data1)

测试打印:

库定义相关元方法

__tostring

当要打印表名时,Lua就会查找该表的元表中的__tostring方法,并调用;将对象作为参数传给该函数,然后把元方法的返回值返回。

Lua 复制代码
local animal = {
   name = "动物"
}

local cat = {
   name = "小猫咪"
}

setmetatable(cat,animal)

animal.__tostring = function(t)
   print(t.name)
   return "动物方法"
end

print(cat)

__call

当表被当做一个函数被调用时,Lua就会查找该表的元表中的__call方法,并调用

Lua 复制代码
local animal = {
   name = "动物"
}

local cat = {
   name = "小猫咪"
}

setmetatable(cat,animal)

animal.__call = function(t)
   print("我是"..t.name.."的方法")
end

cat()

表相关元方法

__index

当访问一个表中不存在的字段时,那么Lua就会寻找该table的metatable中的__index 键

元方法是一个表

Lua 复制代码
local Human = {}
Human.__index = {
   score = 250
}
local Student = {}

setmetatable(Student,Human)
print(Student.score)

元方法是一个函数

Lua 复制代码
local Human = {}
Human.__index = function()
   print("调用index元方法")
   return 1000
end
local Student = {}
setmetatable(Student,Human)
print(Student.score)

__newindex

当给表中一个不存在的键赋值时,首先判断该表是否有元表,如果没有则相当于直接在表中声明一个变量并赋值,如果有则在元表中查找__newindex键,如果__newindex包含一个表则直接在该表中赋值,不在原始表中赋值。

__newindex 元方法用来对表更新,__index则用来对表访问 。

rawset

在不触发元方法__newindex的情况下,在原始表中进行声明赋值.

未用rawset情况:如果直接赋值的话,会查找tab2的元表中的元方法__newindex,将在元表tab1中声明该键并赋值,而不在tab2中声明赋值

使用rawset情况:当元表中有元方法__newindex时,使用rawset,给tab2中的不存在的键赋值,不会调用元方法__newindex,直接在tab2中声明赋值

rawget

在不触发元方法__index的情况下,直接在原始表中查找该字段

Lua 复制代码
local Human = {
  score = 100
}

Human.__index = {
   score = 250
}

local Student = {}
setmetatable(Student,Human)
print(rawget(Student,"score"))
相关推荐
慢慢沉2 天前
Lua(数据库访问)
开发语言·数据库·lua
慢慢沉2 天前
Lua协同程序(coroutine)
lua
慢慢沉3 天前
Lua元表(Metatable)
lua
慢慢沉3 天前
Lua(字符串)
开发语言·lua
慢慢沉3 天前
Lua(数组)
开发语言·lua
慢慢沉3 天前
Lua(迭代器)
开发语言·lua
慢慢沉4 天前
Lua基本语法
开发语言·lua
Feng.Lee4 天前
接口测试Postman工具高级使用技巧
功能测试·测试工具·lua·postman·可用性测试
三翼鸟数字化技术团队4 天前
鸿蒙平台运行Lua脚本
lua·harmonyos