Menu
CoddyTech

对象拼接

本课属于 Coddy Lua 学习旅程的“面向对象编程”单元。第 28 课,共 70 课。

Lua 中的 .. 运算符可以拼接字符串,但如果你想把对象和字符串组合起来,该怎么办?__concat 元方法可以让你准确地定义这种操作的方式。

当 Lua 遇到 a .. b,且其中一个操作数具有 __concat 元方法时,它会将两个值都传给该函数。当你希望对象自然地融入字符串表达式时,这很有用。

local Name = {}
Name.__index = Name

function Name:new(first, last)
    local obj = {first = first, last = last}
    setmetatable(obj, Name)
    return obj
end

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

注意,这个函数会检查哪个操作数是字符串。由于 .. 可以用于 "Hello " .. obj 或 obj .. "!",你的元方法应该处理这两种情况。

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- 输出:Dr. Ada Lovelace
print(person .. " PhD")      -- 输出:Ada Lovelace PhD

和其他运算符元方法一样,按照惯例,__concat 会用点号编写,并接收两个操作数作为参数。它与算术元方法的主要区别在于,你通常会处理不同类型的值:你的对象和一个字符串。

challenge icon

挑战

简单

让我们构建一个 Title 类,使它能够自然地融入使用 .. 运算符的字符串表达式中。当你想以清晰直观的方式将对象与字符串组合起来时,这会很有用,例如在某人的称谓前添加尊称或在后面添加后缀。

你将把代码分成两个文件:

  • Title.lua:定义你的 Title 类,并添加一个用于存储称谓字符串的 text 字段。加入 :new(text) 构造函数,并实现 __concat 元方法。你的元方法应处理两种情况:字符串在对象前面("prefix" .. obj),以及字符串在对象后面(obj .. "suffix")。结果应将字符串与称谓文本恰当地组合起来。
  • main.lua:加载你的 Title 模块,创建一个称谓实例,并演示从两个方向进行字符串拼接。

你会收到三个输入:

  1. 称谓文本(例如,"Engineer")
  2. 要放在称谓前面的前缀字符串(例如,"Senior ")
  3. 要放在称谓后面的后缀字符串(例如," III")

在主文件中,使用给定的文本创建一个 Title。然后进行两次字符串拼接,并将每个结果分别打印在单独的一行:

  1. 将前缀字符串与称谓对象拼接
  2. 将称谓对象与后缀字符串拼接

例如,如果输入是 Engineer、Senior 和 III,输出应为:

Senior Engineer
Engineer III

第一行显示前缀与称谓的组合,第二行显示称谓与后缀的组合。你的 __concat 元方法让这种自然的字符串拼接成为可能!

亲手试试

-- 读取输入
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

-- 加载 Title 模块
local Title = require('Title')

-- TODO: 使用给定的 titleText 创建一个 Title 实例

-- TODO: 将 prefix 与 title 对象拼接,并打印结果

-- TODO: 将 title 对象与 suffix 拼接,并打印结果
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Lua 在线编译器