在我进入这个之前,我强烈建议对你打算对最左边的运算符执行的任何特殊操作使用额外的操作。__unm
或者__len
将是明显的选择,因为它们是一元的。因此,例如,您的陈述可能看起来像
local x = -(a .. b .. c)
这将使您的代码更好地遵循,否则您的连接操作将不可替代,并且还会失去默认..
运算符的关联性。我的意思是,根据您的预期操作,这些等式将是正确的:
a .. b .. c ~= a .. (b .. c)
(a .. b ) .. c ~= a .. (b .. c)
话虽如此:我不认为你可以在 Lua 中检测到最左边的操作 - 至少在分配之前,但你可以检测到最右边的操作。
由于您没有准确地写出您打算做什么,我只想指出您的操作可能可以改变,以便您以不同的方式处理最右边的操作并最终获得相同的结果,所以这里有一些示例代码
local MT = {};
local registry = setmetatable({}, {__mode == "k"});
function MT.__concat(left, right)
if not registry[right] then
print("rightmost operation", left, right);
end
local r = newTT(left.val .. right.val);
registry[r] = true;
return r;
end
function MT:__tostring()
return tostring(self.val);
end
function newTT(v)
return setmetatable({ val = v }, MT);
end
local a = newTT("A");
local b = newTT("B");
local c = newTT("C");
local d = newTT("D");
local x = a .. (b .. c) .. d;
local y = a .. (c .. b) .. d;
local z = a .. b .. x; -- the b .. x op will not be detected as rightmost!
您可能可以通过在每个刻度上重置注册表来解决我在最后一行中指出的问题,但实际上这种行为会使操作更可预测。或者至少在我看来。
不管怎样,你可以看到,做这样的事情会引入一大堆新问题,这些问题很可能不值得他们付出努力来解决。