是否有可能手动获取' yield '值而不是在循环中



以文档中的示例为例,我们可以发送一个块来接收函数的yield值。

def twice
  yield 1
  yield 2
end
twice do |i|
  puts i
end

我想知道的是,如果我们可以手动调用该函数,以便第一次调用给出1,然后我们做其他事情,然后下一次调用给出2

我尝试了(只是猜测)各种各样的东西,像puts twice(),但无济于事。有什么办法可以做到吗?

可以使用刷出和通道。这是你能得到的最接近的:

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

并且可能使用包装结构使其看起来像Iterator (http://crystal-lang.org/api/Iterator.html)。但请注意,这有点慢,至少比使用迭代器或常规的非捕获块调用慢得多。

相关内容

  • 没有找到相关文章

最新更新