coroutine

显示已弃用

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

一个 协程 用于在同一脚本内同时执行多个任务。这些任务可能包括从输入中产生值或在解决更大问题时对子程序进行工作。一个任务甚至不需要有定义的结束点,但它需要定义特定时间,在那里它 产生 (暂停)让其他事情被处理。

使用协程

通过提供函数给 coroutine.create() 可以创建新的协程。创建后,一个协程不会在第一次调用 coroutine.resume() 传递参数给函数之前开始运行。当函数停止或调用 coroutine.yield() 时,此调用会返回,当这发生时,coroutine.resume() 返回函数返回的值、发送到 coroutine.yield() 的值或错误消信息。如果出错,第二个返回值是投掷的错误。


local function task(...)
-- 这个函数可能会为一点工作,然后产生一些值
coroutine.yield("first") -- 由 coroutine.resume() 返回
-- 函数在被再次中断后继续执行
return "second"
end
local taskCoro = coroutine.create(task)
-- 第一次调用恢复,这会从一开始运行函数
local success, result = coroutine.resume(taskCoro, ...)
print(success, result) --> 真实,第一个(任务称为 coroutine.yield())
-- 继续运行函数直到它输出或停止
success, result = coroutine.resume(taskCoro)
print(success, result) --> true, second (task halted because it returned "second")

在协程的生命周期内,您可以调用 coroutine.status() 来检查其状态:


<th>意义</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>暂停</b></td>
<td>协程正在等待被恢复。协程在此状态开始,当其函数调用 <code>coroutine.yield()</code> 时进入状态。</td>
</tr>
<tr>
<td><b>运行中</b></td>
<td>正在运行的协程。</td>
</tr>
<tr>
<td><b>正常</b></td>
<td>协程正在等待另一个协程的产生;换言之,它已经恢复了另一个协程。</td>
</tr>
<tr>
<td><b>死亡</b></td>
<td>函数已停止(返回或抛出错误)。该协程无法继续使用。</td>
</tr>
</tbody>
状态

包装核心线程

当使用协程时,您还可以放弃使用协程对象,而是使用包装函数。这样的包装函数会在调用时恢复特定的协程,并且只返回已提供的值。您可以使用 coroutine.wrap() 来执行此操作:


-- 创建协程并返回一个将其重新启动的包装函数
local f = coroutine.wrap(task)
-- 如果我们调用了 coroutine.resume(),继续执行协程
local result = f()
-- 如果出现错误,它将在这里被提起!
-- This differs from coroutine.resume() which acts similar to pcall()

coroutine.resume() 返回的第一个值描述是否有错误发生的协程运行。然而,由 coroutine.wrap() 返回的函数不会这样做:相反,它们直接返回返回或传给 coroutine.yield() 的值,如果有。如果在运行协程函数时出现错误,错误将在返回的函数调用时提出。

生产者模式示例

想象一个生成单词重复的任务:每次生成重复,下一个任务将生成一个更多。例如,提供 Hello 将产生 Hello , HelloHello , HelloHelloHello 等。要做到这一点,您可以定义 repeatThis() :


-- 这个函数每次复用它的协程时重复一个单词
local function repeatThis(word)
local repetition = ""
while true do
-- 进行一次重复然后获得结果
repetition = repetition .. word
coroutine.yield(repetition)
end
end

要将此函数作为协程运行,您可以使用 coroutine.create() 后跟随多个调用 coroutine.resume() :


local repetitionCoro = coroutine.create(repeatThis)
print(coroutine.resume(repetitionCoro, "Hello")) -- 真的,你好
print(coroutine.resume(repetitionCoro)) -- 真实,HelloHello
print(coroutine.resume(repetitionCoro)) -- true, HelloHelloHello

对于这个生产者函数,您也可以使用 coroutine.wrap() 来获得产生值的函数:


local f = coroutine.wrap(repeatThis)
print(f("Hello")) -- 您好
print(f()) -- 你好你好
print(f()) -- HelloHelloHello

概要

职能

职能

close

关闭并将提供的协程处于死状态。此函数返回 true 除非协程处于错误状态,否则返回 false 和错误消信息。当前运行的协程无法关闭。关闭后,不能恢复并行线程。

参数

返回

true 除非关闭的协程处于错误状态。

Variant<string, ()>

如果有的话,错误消信息。

create

创建一个新的协程,其体必须是 Luau 函数。

参数

返回

isyieldable

返回 true 如果在可安全产生的情况下调用此函数的协程,它将返回。禁止在 metamethods 或 C 函数内放弃协程,除了 pcallxpcall 之外。

返回

是否在这一点上可以安全地产生协程。

resume

开始或继续执行协程 co 。第一次恢复协程时,它开始运行其体。值 ... 被传递为身体函数的参数。如果协程已经退出,重新启动它;值 ... 被传递为从退出中获得的结果。如果协程没有任何错误地运行,则恢复返回真正加任何传递给 yield(如果协程产生)或体系函数返回的任何值(如果协程结束)。如果出现任何错误,则返回错误加错误消信息。

参数

...: Variant

返回

running

返回运行中的协程。

返回

status

返回 coroutine 的状态,作为字符串:'运行',如果 coroutine 正在运行(即,它调用了状态);'暂停',如果 coroutine 在调用中被暂停,或者还没有开始运行;'正常',如果 coroutine 是活的但还没有开始运行(即,它已经恢复了另一个 coroutine);和 '死亡',如果 coroutine 已经完成了其身体功能,或者已经停止了运行。

参数

返回

创建一个新的协程,其中体积 f。f必须是 Luau 函数。返回每次调用时恢复协程的函数。传给函数的任何参数都会作为额外参数来继续。返回与恢复相同的值,除了第一个 boolean 外。在出现错误时,传播错误。

参数

返回

yield

Tuple<Variant>

暂停调用协程的执行。要返回的任何参数都作为额外结果传递以继续。禁止在 metamethods 或 C 函数内放弃协程,除了 pcallxpcall 之外。

参数

...: Tuple

返回

Tuple<Variant>