Lua - 協程:初學者指南

前言

你好,未來的程式設計師們!今天,我們將踏上一段令人興奮的旅程,探索Lua協程的神秘世界。我知道你們現在可能會怎麼想:"協程?這聽起來很複雜!" 但別擔心,我會一步步地引導你們了解這個概念,就像我過去幾年來對無數學生所做的一樣。

Lua - Coroutines

想像你正在閱讀一本扣人心弦的書,但你需要休息一下。你放下一個書籤,關上書,稍後再回來從你停止的地方繼續閱讀。這就是協程在程式設計中的做法!它們讓一個程序在某一點暫停執行,然後稍後從那個精確的位置恢復。

在Lua中,協程是一種在單個程序中擁有多個"線程"執行的方式。但與傳統線程不同,協程是合作的,意味著它們自願放棄控制權,而不是被操作系統搶佔。

協程中可用的函數

在我們深入範例之前,讓我們先看看在Lua中使用協程時主要的函數。我會以表格的形式呈現這些函數,方便參考:

函數 描述
coroutine.create() 創建一個新的協程
coroutine.resume() 開始或繼續執行一個協程
coroutine.yield() 暫停一個協程的執行
coroutine.status() 返回一個協程的狀態
coroutine.wrap() 創建一個恢復協程的函數

如果這些函數現在對你來說還不是很清楚,別擔心。我們將在範例中探索每一個!

範例

讓我們從一個簡單的範例開始,看看協程是如何工作的:

function count(start, finish)
for i = start, finish do
print(i)
coroutine.yield()
end
end

co = coroutine.create(count)

coroutine.resume(co, 1, 5)
print("回到主程序")
coroutine.resume(co)
print("再次回到主程序")
coroutine.resume(co)
print("再一次回到主程序")
coroutine.resume(co)

上面的範例做了什麼?

讓我們一步步分解:

  1. 我們定義了一個名為 count 的函數,它接受兩個參數:startfinish

  2. 在函數內部,我們有一個for循環,從 start 打印到 finish。在每次打印後,它調用 coroutine.yield(),這會暫停函數的執行。

  3. 我們使用 coroutine.create(count) 創建一個協程。這並不會立即執行函數;它只是準備讓它作為協程運行。

  4. 我們使用 coroutine.resume(co, 1, 5) 來開始協程。15 會作為參數傳遞給 count 函數。

  5. 協程打印 1 然後暫停。控制權返回到主程序,打印 "回到主程序"。

  6. 我們再次使用 coroutine.resume(co) 恢復協程。它會從上次暫停的地方繼續執行,打印 2,然後再次暫停。

  7. 這個過程會持續,直到協程完成執行。

當你運行這個程序時,你會看到數字與 "回到主程序" 消息交錯出現。就像主程序和協程在輪流出牌!

另一個協程範例

讓我們再看一個範例來加強我們的理解:

function producer()
return coroutine.create(function()
for i = 1, 5 do
coroutine.yield("Item " .. i)
end
end)
end

function consumer(prod)
local status, value = coroutine.resume(prod)
while status and value do
print("消耗: " .. value)
status, value = coroutine.resume(prod)
end
end

-- 創建生產者協程
local prod = producer()

-- 開始消耗
consumer(prod)

在這個範例中,我們有一個生產者-消費者場景:

  1. producer 函數創建一個協程,一次生成一個項目。

  2. consumer 函數接受一個生產者協程,並消耗所有的項目。

  3. 我們創建一個生產者協程並傳遞給消費者。

當你運行這個程序時,你會看到:

消耗: Item 1
消耗: Item 2
消耗: Item 3
消耗: Item 4
消耗: Item 5

這演示了協程如何用於實現合作多任務。生產者以自己的節奏生成項目,而消費者則在項目可用時處理它們。

協程在遊戲開發(用於管理遊戲狀態)、實現迭代器或以同步方式處理異步操作等場景中特別有用。

記住,熟練才能精通!嘗試修改這些範例,玩轉代碼,看看會發生什麼。這是學習編程的最佳方式。而且誰知道呢?也許有一天你會教導下一代程式設計師協程!

未來的Lua大師,快樂編程!

Credits: Image by storyset