2015-10-10 31 views
2

以文檔中的示例爲例,我們可以發送一個從該函數接收yield值的塊。是否可以手動獲取yield值而不是循環?

def twice 
    yield 1 
    yield 2 
end 

twice do |i| 
    puts i 
end 

什麼我不知道,如果我們可以手動在功能調用,這樣第一個電話給1然後我們做其他的東西,然後下一個電話給2

我試過(只是猜測)各種事情,如puts twice()但無濟於事。有什麼辦法可以做到嗎?

回答

4

你可以使用spawn和channels。這是最接近你可以得到:

def foo 
    yield 1 
    yield 2 
end 

chan = Channel(typeof(foo { |x| x })).new 

spawn do 
    foo do |x| 
    chan.send x 
    end 
    chan.close 
end 

p chan.receive? 
p chan.receive? 
p chan.receive? 

http://play.crystal-lang.org/#/r/ijd

你可以在與宏建一個抽象的,也許:

def foo 
    yield 1 
    yield 2 
end 

macro enumerator(call) 
    %chan = Channel(typeof({{call}} { |x| x })).new 
    spawn do 
    {{call}} do |x| 
     %chan.send x 
    end 
    %chan.close 
    end 
    %chan 
end 

values = enumerator(foo) 

p values.receive? 
p values.receive? 
p values.receive? 

http://play.crystal-lang.org/#/r/ije

,可能使用的包裝結構所以它看起來像一個迭代器(http://crystal-lang.org/api/Iterator.html)。但請注意,這樣做比較慢,至少比使用迭代器或常規未捕獲塊調用慢得多。

+0

感謝那個有趣的解決方案,雖然它不適合我的情況。認爲可能有一些功能像ECMAScript6具有其生成器功能,但我可以解決它。再次感謝! –

相關問題