lua的coroutine 協同程序實現迭代器

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

相關文章
相關標籤/搜索