我正在编写 Luau 生产者/消费者模式,其中消费者在协程中运行。尽管我的代码没有使用元方法并且没有 C 调用(无论如何),但我还是收到了
"attempt to yield across metamethod/C-call boundary"
错误。代码:
-- wrap coroutine.resume() to expose errors in resumed coroutine
function resume(...)
ok_result = table.pack(coroutine.resume(...))
if not ok_result[1] then
error(ok_result[2])
end
return table.unpack(ok_result, 2)
end
-- loop using generic 'for'; should work, yes?
function consumer()
print('generic for loop')
for item in coroutine.yield do
print(item)
end
print('generic for done')
end
array = {'loop', 'over', 'yield', 'calls'}
-- just pump array into consumer coroutine
conco = coroutine.create(consumer)
-- run conco up to first yield()
resume(conco)
for _, word in pairs(array) do
resume(conco, word)
end
-- finish with nil to exit the consumer loop
resume(conco)
coroutine.close(conco)
经过相当多的挣扎,我发现这个改变是有效的:
-- straightforward consumer while loop
function consumer()
print('two explicit yield() calls')
item = coroutine.yield()
while item do
print(item)
item = coroutine.yield()
end
print('two explicit yield() calls done')
end
初步结论:使用Luau泛型
for
循环将内部C函数调用拼接到迭代器函数的调用中?
这太不透明了,似乎值得分享这个发现。