字符串功能可以用这种方式:
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)
在字符串操作中存在任何方式吗? 提前谢谢。
答案 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
,这样他们就会自动将你的对象“解包”到基本数值。当然,在此之后,您将无法将您的方法应用于“解包”值。