一个 协程 用于在同一脚本内同时执行多个任务。这些任务可能包括从输入中产生值或在解决更大问题时对子程序进行工作。一个任务甚至不需要有定义的结束点,但它需要定义特定时间,在那里它 产生 (暂停)让其他事情被处理。
使用协程
通过提供函数给 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)) -- 真实,HelloHelloprint(coroutine.resume(repetitionCoro)) -- true, HelloHelloHello
对于这个生产者函数,您也可以使用 coroutine.wrap() 来获得产生值的函数:
local f = coroutine.wrap(repeatThis)print(f("Hello")) -- 您好print(f()) -- 你好你好print(f()) -- HelloHelloHello
概要
职能
关闭并将提供的协程处于死状态。
创建一个新的协程,其体必须是 Luau 函数。
返回 true 如果在可安全产生的情况下调用此函数的协程,它将返回。
开始或继续执行协程 co 。
返回运行中的协程。
返回 coroutine 的状态作为字符串。
创建一个新的协程,并返回一个函数,该函数在调用时恢复协程。
暂停执行协程。