Lua:我如何连接方法,就像字符串方法一样?

时间:2016-02-28 10:10:03

标签: methods lua concatenation

字符串功能可以用这种方式:

string.FUNCTION('myString', PARAMETER)

或将'string'替换为要使用的字符串,并将其称为方法

('myString'):METHOD(PARAMETER)

最后一种方法是非常好读取并允许连接方法。

-- example string operation
some_str, pos = '   some string', 1
-- default string syntax
while string.find(string.sub(some_str, pos, pos), '%s') do pos = pos +1 end
-- the same with syntactic sugar
while some_str:sub(pos, pos):find('%s') do pos = pos +1 end

所以我尝试用自己的函数获得相同的行为。但这失败了。 我发现的唯一方法是使用一个额外的参数来说明:返回对象本身或结果。 这是一个简单的例子。

calc = {
    result = 0,
    operator = '',
    run = function(self, a, b, r) -- return self with r='s'
        if b == 's' then r, b = b, nil end
        if not b then b, a = a, self.result end
        if self.operator == '+' then self.result = (a) + (b)
        elseif self.operator == '-' then self.result = (a) - (b)
        elseif self.operator == '*' then self.result = (a) * (b)
        elseif self.operator == '/' then self.result = (a) / (b) end
        if r ~= nil then return self else return self.result end
    end,
    add = function(self, a, b, r) self.operator = '+' return self:run(a, b, r) end,
    sub = function(self, a, b, r) self.operator = '-' return self:run(a, b, r) end,
    mul = function(self, a, b, r) self.operator = '*' return self:run(a, b, r) end,
    div = function(self, a, b, r) self.operator = '/' return self:run(a, b, r) end
}

-- single operation
result = calc:add(12, 5)

-- concatenated operations
result = calc:add(12, 5, 's'):sub(3, 's'):mul(2, 's'):div(7)

在字符串操作中存在任何方式吗? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

您的后续呼叫会将's'分配给b参数,而不是r。当然检查return self失败了。不是给带有某些标志的方法赋予不同的行为,而是使它们始终return self而是使用单独的方法来返回当前结果 - 读取和编程将更加清晰。

之后,您的通话将如下:

result = calc:new(12):add(5):sub(3):mul(2):div(7):result()

此外,你真的不需要代理函数进入一个分为if的大函数 - 只需做add / sub / {{1}内的所有事情。 } / mul他们自己。

您可能也需要多个calc对象,每个对象都有自己独立的当前结果。将常用函数存储在metatable中,并使div使用此metatable和单独的条目创建新实例。

:new

你无法完全复制Lua的字符串行为 - 它内置于VM中,可以将local calc_meta = { __index = { add = function(self, number) self._r = self._r + number return self end, sub = function(self, number) self._r = self._r - number return self end, mul = function(self, number) self._r = self._r * number return self end, div = function(self, number) self._r = self._r / number return self end, result = function(self) return self._r end }} local calc = { new = function(self, number) return setmetatable({ _r = number or 0 }, calc_meta) end } result = calc:new(12):add(5):sub(3):mul(2):div(7):result() print(result) -- 4 表视为字符串值的元数据,并且无需修改VM本身就无法编程。如果你将string / result和其他数字方法添加到metatable中,你可以在最后删除额外的__add,这样他们就会自动将你的对象“解包”到基本数值。当然,在此之后,您将无法将您的方法应用于“解包”值。