<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢(mèng)蝶

    生活、程序、未來(lái)
       :: 首頁(yè) ::  ::  :: 聚合  :: 管理

        Ruby Fiber指南(一)基礎(chǔ)
        Ruby Fiber指南(二)參數(shù)傳遞
        Ruby Fiber指南(三)過(guò)濾器
        Ruby Fiber指南(四)迭代器
        Ruby Actor指南(五)實(shí)現(xiàn)Actor

         上一節(jié)介紹了利用Fiber實(shí)現(xiàn)類unix管道風(fēng)格的過(guò)濾鏈,這一節(jié)將介紹利用Fiber來(lái)實(shí)現(xiàn)迭代器,我們可以將循環(huán)的迭代器看作生產(chǎn)者-消費(fèi)者模式的特殊的例子。迭代函數(shù)產(chǎn)生值給循環(huán)體消費(fèi)。所以可以使用Fiber來(lái)實(shí)現(xiàn)迭代器。協(xié)程的一個(gè)關(guān)鍵特征是它可以不斷顛倒調(diào)用者與被調(diào)用者之間的關(guān)系,這樣我們毫無(wú)顧慮的使用它實(shí)現(xiàn)一個(gè)迭代器,而不用保存迭代函數(shù)返回的狀態(tài),也就是說(shuō)無(wú)需在迭代函數(shù)中保存狀態(tài),狀態(tài)的保存和恢復(fù)交由Fiber自動(dòng)管理。

         這一節(jié)的介紹以一個(gè)例子貫穿前后,我們將不斷演化這個(gè)例子,直到得到一個(gè)比較優(yōu)雅的可重用的代碼,這個(gè)例子就是求數(shù)組的全排列。如數(shù)組[1,2,3]的全排列包括6種排列:
    2 3 1
    3 2 1
    3 1 2
    1 3 2
    2 1 3
    1 2 3
    全排列的遞歸算法實(shí)現(xiàn)很簡(jiǎn)單,我們用Ruby實(shí)現(xiàn)如下:

    #全排列的遞歸實(shí)現(xiàn)
    def permgen (a, n)
        
    if n == 0 then
           printResult(a)
        
    else
            n.times do 
    |i|
               a[n
    -1], a[i] = a[i], a[n-1]
               permgen(a, n 
    - 1)
               a[n
    -1], a[i] = a[i], a[n-1]
           end
        end
    end

    def printResult (a)
        puts a.join(
    " ")
    end

    permgen([
    1,2,3,4],4)
    算法的思路是這樣:
    將數(shù)組中的每一個(gè)元素放到最后,依次遞歸生成所有剩余元素的排列,沒(méi)完成一個(gè)排列就打印出來(lái)。很顯然,這里有消費(fèi)者和生產(chǎn)者的關(guān)系存在,生產(chǎn)者負(fù)責(zé)產(chǎn)生排列,消費(fèi)者負(fù)責(zé)打印任務(wù),整個(gè)程序由消費(fèi)者驅(qū)動(dòng),因此用Fiber改寫如下:

    第一步,將打印任務(wù)修改為Fiber#yield,生產(chǎn)者產(chǎn)生一個(gè)排列后將結(jié)果傳遞給消費(fèi)者并讓出執(zhí)行權(quán):
    def permgen (a, n)
        
    if n == 0 then
           Fiber.
    yield(a)
        ……
    end

    第二步,實(shí)現(xiàn)一個(gè)迭代器工廠,返回一個(gè)匿名的迭代函數(shù),迭代函數(shù)請(qǐng)求Fiber產(chǎn)生一個(gè)新的排列:
    def perm(a)
      f
    =Fiber.new do
            permgen(a,a.size)
        end
      
    return lambda{ f.resume if f.alive? }
    end

    這樣一來(lái)我們就可以利用一個(gè)while循環(huán)來(lái)打印全排列:
    it=perm([1,2,3,4])

    while a=it.call
       printResult(a)
    end

        注意到,在perm方法中有一個(gè)很常見(jiàn)的模式,就是將對(duì)Fiber的resume封裝在一個(gè)匿名函數(shù)內(nèi),在lua為了支持這種模式還特意提供了一個(gè)coroutine.wrap方法來(lái)方便編程,在Ruby Fiber中卻沒(méi)有,不過(guò)我們可以自己實(shí)現(xiàn)下,利用open-class的特性實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單:
    #為Fiber添加wrap方法
    class Fiber
      
    def self.wrap
        
    if block_given?
          f
    =Fiber.new do |*args|
             
    yield *args
          end
          
    return lambda{|*args| f.resume(*args) if f.alive? }
        end
      end
    end
     
        Fiber#wrap方法跟new方法一樣,創(chuàng)建一個(gè)新的Fiber,但是返回的是一個(gè)匿名函數(shù),這個(gè)匿名函數(shù)負(fù)責(zé)去調(diào)用fiber的resume,利用wrap改寫perm方法變得更簡(jiǎn)潔:
    def perm(a)
      Fiber.wrap{ permgen(a,a.size) }
    end

        但是還不夠,while循環(huán)的方式還是不夠優(yōu)雅,每次都需要明確地調(diào)用迭代器的call方法,這一點(diǎn)讓人挺不舒坦,如果能像for...in那樣的泛型循環(huán)就好了,我們知道Ruby中的for...in其實(shí)是一個(gè)語(yǔ)法糖衣,都是轉(zhuǎn)變成調(diào)用集合的each方法并傳入處理的block,因此,要想實(shí)現(xiàn)一個(gè)優(yōu)雅的迭代器,我們做下封裝就好了:

    class FiberIterator
      
    def initialize
        @fiber_wrap
    =Fiber.wrap do
            
    yield
        end
      end
      
    def each
        
    while value=@fiber_wrap.call
          
    yield value
        end
      end
    end

    那么現(xiàn)在的perm方法變成了創(chuàng)建一個(gè)迭代器FiberIterator:
    def perm(a)
      FiberIterator.new{ permgen(a,a.size) }
    end
    這樣一來(lái)我們就可以通過(guò)for...in來(lái)調(diào)用迭代器了

    it=perm([1,2,3,4])
    for a in it
      printResult(a)
    end


       

        
    主站蜘蛛池模板: 欧美a级在线现免费观看| 久久成人免费大片| 国产一级理论免费版| 亚洲av无码久久忘忧草| 国产精品久久久久免费a∨| 亚洲小视频在线播放| 国产va免费精品观看精品| 91在线亚洲综合在线| 麻豆国产入口在线观看免费| 亚洲欧美aⅴ在线资源| 日韩视频免费在线| 黄色大片免费网站| 亚洲综合AV在线在线播放| 一区二区三区无码视频免费福利| 亚洲AV无码乱码国产麻豆穿越| 亚洲精品视频免费在线观看| 亚洲av乱码一区二区三区香蕉| 成人au免费视频影院| 三级片免费观看久久| 亚洲AV综合色区无码一区爱AV| 久久免费观看国产精品88av| 亚洲女人影院想要爱| 国产精品色午夜视频免费看| a毛片成人免费全部播放| 亚洲国产成人久久综合碰碰动漫3d| 最近中文字幕免费2019| 亚洲欧美不卡高清在线| 亚洲一区二区三区自拍公司| 亚洲高清免费在线观看| 国产精品国产亚洲区艳妇糸列短篇| 亚洲国产人成中文幕一级二级| 日本免费污片中国特一级| 亚洲不卡影院午夜在线观看| 亚洲精品99久久久久中文字幕 | a级毛片100部免费观看| 91嫩草私人成人亚洲影院| 全免费a级毛片免费看无码| 中文日本免费高清| 亚洲www在线观看| 亚洲精品午夜无码专区| 色妞WWW精品免费视频|