我有一个辅助函数,它返回一个这样的表:
function of_type(expected_type)
return {
expected = expected_type,
matches = function(value) return type(value) == expected_type end,
describe = "type " .. expected_type
}
end
现在这对其他匹配器来说很好,但是在这里我想在调用type(value)
函数时将matches
存储到同一个表中的一个字段中。像这样:
function of_type(expected_type)
return {
expected = expected_type,
mismatch = nil, -- set it to nil on initialization
matches = function(value)
mismatch = type(value) -- how to do this?
return type(value) == expected_type
end,
describe = "type " .. expected_type
}
end
这可能吗?
答案 0 :(得分:2)
是的,但您需要将其拆分为以下步骤:
function of_type(expected_type)
local tbl = {
expected = expected_type,
mismatch = nil, -- set it to nil on initialization
describe = "type " .. expected_type
}
tbl.matches = function(value)
tbl.mismatch = type(value)
return type(value) == tbl.expected
end
return tbl
end
-- testing it
local foo = of_type("string")
print(foo.matches(1), foo.matches("1"))
这应该按照您的预期输出false true
。
基本上,tbl.matches
将存储对tbl
的引用(称为“upvalue”),并且能够修改该表中的所有字段(包括对其自身的引用)。 / p>
执行此操作的另一种方式如下(请注意tbl.matches函数中的更改)。您可以使用tbl:method
语义并将tbl
作为隐式self
参数传递而不是将其作为upvalue捕获:
function of_type(expected_type)
local tbl = {
expected = expected_type,
mismatch = nil, -- set it to nil on initialization
describe = "type " .. expected_type
}
function tbl:matches(value)
self.mismatch = type(value) -- how to do this?
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)
相同。
答案 1 :(得分:1)
你没有。好吧,不是没有存储表的副本,或者将表作为参数传递给表。在处理完表结构的所有语句之前,该表尚不存在。而且由于你从未将它存储在任何地方(在这个函数中),你的函数不能命名它以便找到它。
所以你应该给它一个名字,即使只是片刻:
function of_type(expected_type)
local temp = nil
temp = {
expected = expected_type,
mismatch = nil, -- set it to nil on initialization
matches = function(value)
temp.mismatch = type(value) -- Like this
return type(value) == expected_type
end,
describe = "type " .. expected_type
}
return temp
end
这是有效的,因为Lua会将temp
存储为upvalue。因此,您正在创建的函数将在temp
中看到更改,例如将其设置为表值时。因为它是一个局部变量,所以在这个函数之外它是不可见的。