Menu
CoddyTech

算术元方法(上)

本课属于 Coddy Lua 学习旅程的“逻辑与流程”单元。第 21 课,共 54 课。

你已经学会了如何自定义使用 __tostring 打印表时发生的情况。现在你将了解,元表还可以定义对表使用 + 和 - 等算术运算符时会发生什么。

通常,如果你尝试用 + 运算符将两个表相加,Lua 会报错,因为它不知道如何将表相加。不过,借助算术元方法,你可以为自定义数据类型明确定义加法的含义。

__add 元方法控制加法行为。当 Lua 遇到两个值之间的 + 运算符,并且至少有一个值带有包含 __add 的元表时,它会调用该函数,而不是报错:

local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}

local meta = {
    __add = function(a, b)
        return {x = a.x + b.x, y = a.y + b.y}
    end
}

setmetatable(v1, meta)
setmetatable(v2, meta)

local v3 = v1 + v2
print(v3.x, v3.y)  -- 输出:4  6

__add 函数接收两个参数:左操作数和右操作数。在这个示例中,它会创建一个新表,其中的 x 和 y 值分别是两个输入表中对应值的和。

同样,__sub 元方法通过 - 运算符控制减法:

local meta = {
    __sub = function(a, b)
        return {x = a.x - b.x, y = a.y - b.y}
    end
}

setmetatable(v1, meta)
setmetatable(v2, meta)

local v3 = v1 - v2
print(v3.x, v3.y)  -- 输出:2  2

这种定义自定义运算符行为的能力称为运算符重载。

challenge icon

挑战

简单

编写一个函数 addVectors,接收 x1、y1、x2 和 y2,并返回两个向量相加的结果。

使用给定的坐标创建两个向量表,附加一个包含 __add 元方法的元表,以启用向量加法;使用 + 运算符将它们相加,并将结果作为格式化字符串返回。

逻辑:

  • 创建第一个向量表,键为 x = x1 和 y = y1
  • 创建第二个向量表,键为 x = x2 和 y = y2
  • 创建一个包含 __add 的元表,该元方法接收两个向量,并返回一个新表,其中 x = a.x + b.x,y = a.y + b.y
  • 使用 setmetatable() 将元表附加到两个向量表上
  • 使用 v1 + v2 将两个向量相加
  • 将结果作为字符串返回,格式为 "x y"(x 和 y 的值之间用空格分隔)

参数:

  • x1(数字):第一个向量的 x 坐标
  • y1(数字):第一个向量的 y 坐标
  • x2(数字):第二个向量的 x 坐标
  • y2(数字):第二个向量的 y 坐标

返回值:两个向量的和,作为格式为 "x y" 的字符串返回(字符串)

亲手试试

function addVectors(x1, y1, x2, y2)
    -- 在这里编写代码
end
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: Lua 在线编译器