找回密码
马上加入

QQ登录

只需一步,快速开始

搜索
发新帖

0

收听

2

听众

108

主题
发表于 2024-6-20 22:39:53 | 查看: 224| 回复: 0
Lua 基础教学:第十一篇高级元表与元方法
在本篇文章中,我们将深入探讨 Lua 中的高级元表与元方法。元表(metatable)和元方法(metamethods)是 Lua 强大的特性之一,允许我们自定义表的行为。
回顾元表和元方法
在之前的教程中,我们已经了解了如何为表设置元表,并使用元方法改变表的行为。我们复习一下基本用法:
local t = {}
local mt = {
    __index = function(table, key)
        return "default value"
    end
}

setmetatable(t, mt)
print(t.somekey)  -- 输出:default value高级元方法
元方法可以用来实现表的各种高级行为,例如运算符重载、方法调用、保护元表等。
运算符重载
可以通过定义元方法,实现表的运算符重载。常用的元方法包括:
  • __add: 加法运算符 +
  • __sub: 减法运算符 -
  • __mul: 乘法运算符 *
  • __div: 除法运算符 /
  • __mod: 取模运算符 %
  • __pow: 幂运算符 ^
  • __concat: 连接运算符 ..
  • __eq: 相等运算符 ==
  • __lt: 小于运算符 <
  • __le: 小于等于运算符 <=

示例:加法运算符local vector = {}
vector.__index = vector

function vector.new(x, y)
    local v = setmetatable({}, vector)
    v.x = x
    v.y = y
    return v
end

function vector.__add(a, b)
    return vector.new(a.x + b.x, a.y + b.y)
end

local v1 = vector.new(1, 2)
local v2 = vector.new(3, 4)
local v3 = v1 + v2
print(v3.x, v3.y)  -- 输出:4 6方法调用
可以使用 __call 元方法定义表的调用行为:
local callable = {}
callable.__call = function(table, arg)
    print("Called with argument: " .. arg)
end

local t = setmetatable({}, callable)
t("Hello")  -- 输出:Called with argument: Hello保护元表
为了防止直接访问或修改元表,可以使用 __metatable 元方法:
local t = {}
local mt = {
    __metatable = "protected"
}

setmetatable(t, mt)
print(getmetatable(t))  -- 输出:protected
setmetatable(t, {})     -- 错误:cannot change a protected metatable自定义迭代器
Lua 中的 pairs 和 ipairs 函数用于迭代表,但我们也可以自定义迭代器,使用 __pairs 和 __ipairs 元方法:
示例:自定义 pairslocal customPairs = {}
customPairs.__index = customPairs

function customPairs.new()
    local t = setmetatable({}, customPairs)
    t.data = {a = 1, b = 2, c = 3}
    return t
end

function customPairs:__pairs()
    return next, self.data, nil
end

local t = customPairs.new()
for k, v in pairs(t) do
    print(k, v)  -- 输出:a 1, b 2, c 3
end代理表
代理表是一种使用元表实现的高级技巧,允许我们在一个表上操作,但实际数据存储在另一个表中。
示例:代理表local actualData = {}
local proxy = {}

local mt = {
    __index = function(table, key)
        return actualData[key]
    end,
    __newindex = function(table, key, value)
        actualData[key] = value
    end
}

setmetatable(proxy, mt)

proxy.foo = "bar"
print(proxy.foo)          -- 输出:bar
print(actualData.foo)     -- 输出:bar总结
在这篇教程中,我们深入探讨了 Lua 中的高级元表与元方法。我们学习了如何使用元方法实现运算符重载、自定义方法调用、保护元表、自定义迭代器和代理表。这些技巧使得 Lua 的表变得更加灵活和强大。在接下来的教程中,我们将探讨 Lua 的协程(coroutines)和并发编程。
继续关注我们的 Lua 教程系列,如果你有任何问题或建议,请在评论区留言。
您需要登录后才可以回帖 登录 | 马上加入

QQ|Archiver|手机版|小黑屋|alg阿灵戈社区 ( 苏ICP备2023026137号-1|苏ICP备2023026137号-1 )

GMT+8, 2025-3-13 04:34 , Processed in 0.524273 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表