在 Lua 中实现类似于 Swift Extension 的机制
程序员文章站
2022-03-14 11:01:07
...
本文目标
本文在 Lua 中实现类似于 Swift Extension 的机制,使得在不改变类继承关系、不进行重复代码实现的前提下,实现一些函数的复用。主要作用是减少代码重复。主要思路是在运行时将作为 extensionClass 的表的元素依次拷贝到目标类中。
软件版本
- Lua 5.1.5
代码
遍历扩展类/表,将其中的对象依次拷贝到目标类中。具体实现如下:
function extendClass(extensionDestinationClass, extensionSourceClass)
for k, v in pairs(extensionSourceClass) do
if extensionDestinationClass[k] ~= nil then
print("key "..k.." overriden by extension class")
end
extensionDestinationClass[k] = v
end
end
说明
该实现对 number 是按值拷贝,对 string(按 Lua 实现机制,本身就是存储的引用), function, table 是按引用拷贝。
相对于 Swift 的 extension 语法,因为此处 extension 类在定义时不需要指明是对哪个类的扩展,所以一次定义后可用于多种不同的类。而 Swift 则一个 extension 定义对应一个特定的实现,在这一点上本实现略有优势。
使用示例
testClass = {}
extensionClass = {}
function extensionClass:ExtendedPrint()
print("hello a extended print")
end
extensionClass.testValue = 20
-- 由于搜索的复杂性,多重继承的效率比起单继承
-- 要低。一个简单的改善性能的方法是将继承方法拷贝到子类。
baseClass = {}
function baseClass:BasePrint()
print("hello this is base print")
end
setmetatable(testClass, {__index = baseClass})
testClass:BasePrint()
--testClass:ExtendedPrint()
--setmetatable(testClass, {__index = extensionClass})
extendClass(testClass, extensionClass)
testClass:BasePrint()
testClass:ExtendedPrint()
print(extensionClass)
print(testClass)
extendClass(testClass, extensionClass)
testClass.testValue = 50
testClass2 = {}
extendClass(testClass2, extensionClass)
print(testClass.testValue)
print(testClass2.testValue)
配合 debugPrint模块 可以得到以下输出:
@test.lua(38,1) hello this is base print
@test.lua(38,1) hello this is base print
@test.lua(27,1) hello a extended print
@test.lua(52,1)
{
testValue = 20,
ExtendedPrint = "function: 01044A18"
}
@test.lua(53,1)
{
ExtendedPrint = "function: 01044A18",
testValue = 20
}
@test.lua(10,1) key testValue overriden by extension class
@test.lua(10,1) key ExtendedPrint overriden by extension class
@test.lua(59,1) 50
@test.lua(60,1) 20
可见,testClass 与 testClass2 分别拥有不同的 testValue 实例。但是共用 ExtendedPrint 这个 function 的引用。
示例工程
参考资料
上一篇: 图——关键路径(代码超详细注释)
下一篇: Lua学习记录-3