我该如何在Lua中链接函数调用?

3

我正在尝试编写一个函数来链接函数调用,但它并没有生效。它应该能够在不出现任何问题的情况下打印出执行加法运算后的值。

这是我的第一次尝试:

local _ = {}
function _.add(x, y) return x + y end
function _.lt(x, y) return x < y end

function _.chain(value)
    local mt = {
        __newindex = function(t, k, v)
            t._value = _[k](t._value, v)
        end
    }
    local chain = {
        _value = value,
        value = function(self)
            return self._value
        end
    }
    chain = setmetatable(chain, mt)
    return chain
end

local value = chain(2).add(5)
print(value)

这个解决方案无法正常工作,因为它应该能够通过__newindex元表来本地化函数。但是它没有实现函数的本地化,而是抛出了以下错误信息:
lua: main.lua:21: attempt to call a nil value (method 'add')
stack traceback:
    main.lua:21: in main chunk
    [C]: in ?

我第二次尝试解决这个问题是使用没有元方法的方式:

local _ = {}
function _.add(x, y) return x + y end
function _.lt(x, y) return x < y end

function _.chain(value)
    local t = {
        _value = value;
        value = function (self)
            return self._value
        end
    }
    -- merge methods in t
    for k, v in pairs(_) do
        if type(v) == "function" then
            t[k] = function (self, ...)
                local result = v(self._value, ...)
                if result ~= self._value then
                    self._value = result
                end
                return self
            end
        end
    end
    
    return t
end
local sum = _.chain(2):add(5):value()
print(sum)

这次尝试不起作用,因为它输出nil而不是7

1
更多的是一种风格注意事项,您不应该将“_”用作您实际打算使用的变量名称。这样做违反了“_”是一个变量名称的习惯用法,您将不会使用它,通常像for _, v pairs(t) do这样使用,只有v将在循环体中使用。 - Nifim
1个回答

5

在你的第一次尝试中,你没有向表链中添加新字段,所以方法__newindex从未被调用。而在你的第二次尝试中,我不知道你做错了什么,因为它对我有效,我做了如下操作:

local sum = _.chain(2):add(5):value()
print(sum)

打印了7次

local sum = _.chain(2):add(5):add(3):value()
print(sum)

并打印了10份

local sum = _.chain(2):add(5):add(3):add(7):value()
print(sum)

并打印了17份


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接