reference:數組
http://blog.csdn.net/wzzfeitian/article/details/8832017函數
下面咱們就看一下coroutine爲咱們提供的強大的功能,用coroutine來實現迭代器。oop
咱們來遍歷一個數組的全排列。先看一下普通的loop實現,代碼以下:lua
function printResult(a) for i = 1, #a do io.write(a[i], ' ') end io.write('\n') end function permgen(a, n) n = n or #a if n <= 1 then print("write value") printResult(a) else for i = 1, n do print("start: ", i,n,a[i],a[n]) a[n], a[i] = a[i], a[n] print(a[i],a[n]) permgen(a, n-1) a[n], a[i] = a[i], a[n] print("n: ", n, a[i],a[n]) end end end permgen({"a","b","c"})
執行結果:spa
start: 1 3 a c c a start: 1 2 c b b c write value b c a n: 2 c b start: 2 2 b b b b write value c b a n: 2 b b n: 3 a c start: 2 3 b c c b start: 1 2 a c c a write value c a b n: 2 a c start: 2 2 c c c c write value a c b n: 2 c c n: 3 b c start: 3 3 c c c c start: 1 2 a b b a write value b a c n: 2 a b start: 2 2 b b b b write value a b c n: 2 b b n: 3 c c
再看一下迭代器實現,注意比較下代碼的改變的部分:.net
function printResult(a) for i = 1, #a do io.write(a[i], ' ') end io.write('\n') end function permgen(a, n) n = n or #a if n <= 1 then coroutine.yield(a) else for i = 1, n do a[n], a[i] = a[i], a[n] permgen(a, n-1) a[n], a[i] = a[i], a[n] end end end function permutations(a) local co = coroutine.create(function () permgen(a) end) return function () local code, res = coroutine.resume(co) return res end end for p in permutations({"a", "b", "c"}) do printResult(p) end
運行結果:code
b c a c b a c a b a c b b a c a b c
permutations 函數使用了一個Lua中的常規模式,將在函數中去resume一個對應的coroutine進行封裝。Lua對這種模式提供了一個函數coroutine.wap 。跟create 同樣,wrap 建立一個新的coroutine ,可是並不返回給coroutine,而是返回一個函數,調用這個函數,對應的coroutine就被喚醒去運行。跟原來的resume 不一樣的是,該函數不會返回errcode做爲第一個返回值,一旦有error發生,就退出了(相似C語言的assert)。使用wrap, permutations能夠以下實現:blog
function printResult(a) for i = 1, #a do io.write(a[i], ' ') end io.write('\n') end function permgen(a, n) n = n or #a if n <= 1 then coroutine.yield(a) else for i = 1, n do a[n], a[i] = a[i], a[n] permgen(a, n-1) a[n], a[i] = a[i], a[n] end end end function permutations (a) return coroutine.wrap(function () permgen(a) end) end for p in permutations({"a", "b", "c"}) do printResult(p) end
wrap 比create 跟簡單,它實在的返回了咱們最須要的東西:一個能夠喚醒對應coroutine的函數。 可是不夠靈活。沒有辦法去檢查wrap 建立的coroutine的status, 也不能檢查runtime-error(沒有返回errcode,而是直接assert)。get