prapin 的建议是使用元表来呈现序列的视图,这大致是我的做法。一个可能有帮助的抽象是为段定义一个元表,它可以是一个 0 元函数,它返回一对表和一个偏移索引——我们在这里只使用函数来表示元组。然后我们可以定义一个元表,使这个函数表现得像一个表:
do
local tail_mt = {
__index = function(f, k) local t, i=f(); return t[k+i] end,
__newindex = function(f, k, v) local t,i=f(); t[k+1] = v end,
__len = function(f) local t,i=f(); return #t-i end,
__ipairs = function(f)
local t,i = f ()
return
function (_, j)
if i+j>=#t then
return nil
else
return j+1, t[i+j+1]
end
end, nil, 0
end,
}
tail_mt.__pairs = tail_mt.__ipairs -- prapin collapsed this functionality, so I do too
function tail (t)
if type(t) == "table" then
return setmetatable ( function () return t, 1 end, tail_mt )
elseif type(t) == "function" then
local t1, i = t ()
return setmetatable ( function () return t1, i+1 end, tail_mt )
end
end
end
使用 __index 和 __newindex 元方法,您可以编写 f[2]=f[1]+1 等代码。
尽管这个(未经测试的)代码不会无休止地创建一次性元表,但它可能不如 prapin 的有效,因为它将调用 thunk(0 元函数)来获取它们的内容。但是,如果您可能对扩展功能感兴趣,比如对序列有更一般的看法,我认为这更灵活一些。