有,
我修改了#34;烫发"来自Lua 5.0在线文档的示例:http://www.lua.org/pil/9.3.html。我所做的是将__call()元方法重新命名为perm()函数。但它只运行一次,并报告"无法恢复死coroutine"。知道为什么它没有用吗?
function permgen (a, n)
if n == 0 then
coroutine.yield(a)
else
for i=1,n do
-- put i-th element as the last one
a[n], a[i] = a[i], a[n]
-- generate all permutations of the other elements
permgen(a, n - 1)
-- restore i-th element
a[n], a[i] = a[i], a[n]
end
end
end
function perm (a)
local n = table.getn(a)
return coroutine.wrap(function () permgen(a, n) end)
end
K = {"a","b","c"}
for p in perm(K) do
print(p[1],p[2],p[3])
end
for p in perm(K) do
print(p[1],p[2],p[3])
end
-- everything above is copied from the Lua online document,
-- my modification is the following
setmetatable(K,{__call=perm(K)})
for p in K do
print(p[1],p[2],p[3])
end
-- cannot repeat!
-- perm.lua:44: cannot resume dead coroutine
for p in K do
print(p[1],p[2],p[3])
end
`
答案 0 :(得分:1)
之所以发生这种情况,是因为您只需拨打perm(K)
一次,并将结果分配给__call
元方法。然后使用一次(通过执行in K
)并完成perm
调用返回的协同程序的执行。当你第二次尝试这样做时,协程已经#34;死了#34;这会触发错误。
您需要做的是检测协程是否已经死亡并重新创建它。由于您无法使用coroutine.wrap
执行此操作,因此您需要使用coroutine.create
使用稍微修改过的解决方案版本。这样的事情可能有用:
function perm (a)
local n = table.getn(a)
local co = coroutine.create(function () permgen(a, n) end)
return function () -- iterator
if coroutine.status(co) == 'dead' then co = coroutine.create(function () permgen(a, n) end) end
local code, res = coroutine.resume(co)
if not code then return nil end
return res
end
end
它会在恢复之前检查协同程序的状态,如果它已经dead
,那么它会使用相同的参数从头开始重新创建它。