2016-02-28 54 views
2

字符串funtions可以用此方式使用:Lua:我如何连接方法,就像字符串方法一样?

string.FUNCTION('myString', PARAMETER) 

或字符串替换“串”的使用和调用它的方法

('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) 

存在任何方式来做到这一点,就像字符串操作一样吗? 在此先感谢。

+0

Lua返回一个新的字符串,然后你可以简单地调用新字符串的方法。因此链接。你是否返回了该方法被调用的同一张表? – warspyking

回答

1

您的后续调用将's'指定为b参数,而不是r。当然检查return self失败。而不是给具有某些标志的方法赋予不同的行为,而是使它们始终为return self,并且创建一个单独的方法来返回当前结果 - 读取和编程将会更清晰。

之后,您的通话将看起来像:

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

而且,你不真的需要进入一个大的功能分成if小号反正代理功能 - 只是做内部的一切add/sub/mul/div自己。

您可能还需要多个计算对象,每个计算对象都有自己单独的当前结果。将常见功能存储在metatable中,并使:new用此metatable和单独条目创建新实例以获得结果。

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 

不能完全复制Lua的行为与琴弦 - 它是内置到VM治疗string表作为元表的字符串值,并没有修改VM本身不能进行编程。如果您将__add/__sub和其他数字方法添加到metatable,您可以摆脱额外的result,但它们会自动将您的对象“展开”为基本数值。当然,在此之后,您将无法将您的方法应用于“解包”值。

+0

>您的后续调用将's'分配给b参数,而不是r <我知道,因为我检查给定的参数b是否为's'并将其与r交换。但这只是一个例子。你是对的,可以用单独的方法解决,返回结果。但我很感兴趣:它是如何在字符串库中解决的?结果与对象本身相同。您可以覆盖任何字符串并将其用作字符串方法的对象。它的graetfull,但它是如何工作的? – McBarby

+0

@McBarby,它是内置的Lua VM,你不能完全复制它。扩大答案。 –