Lua中的協同程式之resume-yield間的資料返回研究

NO IMAGE

這次要介紹幾個其實很簡單,但是一定要小心的返回值規則。

1.resume的引數

resume函式除了第一個引數是協同程式外,還能繼續傳其他引數,如下程式碼:
複製程式碼 程式碼如下:
    local co = coroutine.create(function(name)
        print(name);
    end);
    coroutine.resume(co, “resume param”);

resume第二個引數為“resume parame”,這個引數將會傳遞給協同程式的函式。
輸出結果如下:
複製程式碼 程式碼如下:
[LUA-print] resume param

這很簡單,對吧,記住這個規則了,接下來不要混亂了。

2.resume函式的第二個返回值

還記得resume函式的兩個返回值嗎?一個代表協同程式是否正確執行,一個代表錯誤資訊。

那,如果協同程式正確執行,錯誤資訊這個返回值自然就是nil了。

然後,這裡還有一個規則,那就是yield函式的引數可以傳遞到resume的第二個返回值裡。
 
如下程式碼:
複製程式碼 程式碼如下:
    local co = coroutine.create(function(name)
        print(name);
        coroutine.yield(“yield param”);
    end);
    local result, msg = coroutine.resume(co, “resume param”);
    print(“msg:” .. msg);

輸出結果如下:
複製程式碼 程式碼如下:
[LUA-print] resume param
[LUA-print] msg:yield param

這次我們只是加了一句yield的呼叫,同時yield函式我們傳遞了一個引數進去。
而這個函式將作為resume的第二個返回值,前提是,resume函式的第一個返回值是true。
 
怎麼樣?是不是開始有點混亂了?
沒關係,接下來更加混亂。

3.yield的返回值

這次輪到yield的返回值了,來看看下面的程式碼:
複製程式碼 程式碼如下:
    local co = coroutine.create(function(name)
        for i = 1, 2, 1 do
            print(name);
            print(“co:” .. coroutine.yield(“yield param”));
        end
    end);
    for i = 1, 2, 1 do
        print(“=========第” .. i .. “次執行:”)
        local result, msg = coroutine.resume(co, “resume param”);
        print(“msg:” .. msg);
    end

這次的協同程式會執行一個for迴圈,而我們也會呼叫兩次resume函式,輸出結果如下:
複製程式碼 程式碼如下:
[LUA-print] =========第1次執行:
[LUA-print] resume param
[LUA-print] msg:yield param
[LUA-print] =========第2次執行:
[LUA-print] co:resume param
[LUA-print] resume param
[LUA-print] msg:yield param

第一次執行的時候,協同程式第一次被掛起,所以yield的返回要等待第二次resume被呼叫時才能得到。

於是,第二次呼叫resume時,首先就得到了上一次yield的返回值了,這個返回值正是resume的第二個引數。
 
沒錯,resume的第二個返回值是yield的引數,而yield的返回值,是resume的第二個引數。

再簡單一些,resume的返回值是yield的引數,yield的返回值是resume的引數。
同時,resume的第二個引數也能傳遞給協同程式的函式。
 
怎麼樣?稍微有點點混亂了吧?

沒關係喇,更混亂的情況還會接著發生的,呵呵。(小若:呵呵你個頭啊,我走了)

4.協同程式結束,主函式的返回值

這最後一種情況了,那就是協同程式的函式返回值,沒錯,它也能有返回值。
先看程式碼:
複製程式碼 程式碼如下:
    local co = coroutine.create(function(name)
        for i = 1, 2, 1 do
            print(name);
            print(“co:” .. coroutine.yield(“yield param”));
        end
        return “協同程式函式結束喇!”
    end);
    for i = 1, 3, 1 do
        print(“=========第” .. i .. “次執行:”)
        local result, msg = coroutine.resume(co, “resume param”);
        print(“msg:” .. msg);
    end

我在協同程式函式的最後加了一個返回值,僅僅是一個字串。

而resume的呼叫我增加到了3次,這是因為協同程式的for迴圈會執行兩次,也就是會呼叫yield兩次。

所以,需要第三次執行resume函式時,第二次yield才能得到返回。
 
輸出結果如下:
複製程式碼 程式碼如下:
[LUA-print] =========第1次執行:
[LUA-print] resume param
[LUA-print] msg:yield param
[LUA-print] =========第2次執行:
[LUA-print] co:resume param
[LUA-print] resume param
[LUA-print] msg:yield param
[LUA-print] =========第3次執行:
[LUA-print] co:resume param
[LUA-print] msg:協同程式函式結束喇!

前兩次的執行結果沒變,第三次就有點特別。

第三次執行resume時,首先就得到了第二次yield的返回,輸出“co:resume param”。

注意一下,這裡是不會繼續執行print(name);這句程式碼的,也就是說,整個協同程式函式的for迴圈是不會被執行的。

這裡僅僅是第二次的yield函式返回了結果,這個可不能理解錯了。
 
最後,協同程式函式返回一個字串,這個字串做成為resume函式的第二個返回值。
是的,當協同程式執行完畢時,resume的第二個返回值就不再是yield的引數了。

5.結束

好了,這就是我今天不小心掃了幾眼後,就不得不仔細研究的地方了。

雖然暫時還沒了解這些規則的實際應用,但,這必須得記錄下來,因為我很快就會混亂,到時候還得回頭看這篇文章吧~
 
好吧,已經9點了…美好的週五晚上T_T

您可能感興趣的文章:

Lua協同程式函式coroutine使用例項Lua中的協同程式探究舉例詳解Lua中的協同程式程式設計