在Lua中引用包含表的函数

我有一个辅助函数,返回以下表格:

function of_type(expected_type)
    return {
        expected = expected_type,
        matches = function(value) return type(value) == expected_type end,
        describe = "type " .. expected_type
    }
end

现在,这对其他匹配器来说没问题,但在这里,当调用matches函数时,我想将type(value)存储到同一表格中的一个字段中。 像这样:

function of_type(expected_type)
    return {
        expected = expected_type,
        mismatch = nil, --在初始化时将其设置为nil
        matches = function(value)
            mismatch = type(value)  --如何实现呢?
            return type(value) == expected_type
        end,
        describe = "type " .. expected_type
    }
end

这可能吗?

点赞
用户1442917
用户1442917

是的,但你需要分为几个步骤:

function of_type(expected_type)
    local tbl = {
        expected = expected_type,
        mismatch = nil, -- 在初始化时将其设置为 nil
        describe = "type " .. expected_type
    }
    tbl.matches = function(value)
        tbl.mismatch = type(value)
        return type(value) == tbl.expected
    end
    return tbl
end

-- 测试输出
local foo = of_type("string")
print(foo.matches(1), foo.matches("1"))

这应该会像预期的那样输出 false true

实质上,tbl.matches 将存储对 tbl 的引用(它被称为“上值”),并且能够修改该表中的所有字段(包括它自己的引用)。

另一种方法是以下方法(注意 tbl.matches 函数中的更改)。 您可不必将其捕获为上值,还可以使用 tbl:method 语法并将 tbl 作为隐式 self 参数传递:

function of_type(expected_type)
    local tbl = {
        expected = expected_type,
        mismatch = nil, -- 在初始化时将其设置为 nil
        describe = "type " .. expected_type
    }
    function tbl:matches(value)
        self.mismatch = type(value)  -- 怎么做的?
        return type(value) == self.expected
    end
    return tbl
end

local foo = of_type("string")
print(foo:matches(1), foo:matches("1"))

这将输出相同的结果。请注意,您使用 foo:matches 表示法使 foo 作为第一个参数(在该方法中作为 self 引用)进行传递。这与使用 foo.matches(foo, 1) 相同。

2012-09-20 15:25:29
用户734069
用户734069

你不能。嗯,除非在函数中存储表的一份副本,或将表作为参数传递给函数。在表构造函数的所有语句被处理之前,表还不存在。而且由于你没有在任何地方存储它(在该函数中),你的函数无法命名它以便找到它。

因此,你应该给它一个名字,即使只是暂时的:

function of_type(expected_type)
  local temp = nil
  temp = {
        expected = expected_type,
        mismatch = nil, -- 在初始化时将其设置为nil
        matches = function(value)
            temp.mismatch = type(value)  -- 就像这样
            return type(value) == expected_type
        end,
        describe = "type " .. expected_type
    }
  return temp
end

这有效是因为 Lua 将 temp 存储为一个上值。因此,你创建的函数将看到 temp 的变化,例如当你将其设置为一个表值时。而且由于它是一个局部变量,它在该函数之外是不可见的。

2012-09-20 15:26:56