以文档中的这个例子为例,我们可以发送一个yield
从函数接收值的块。
def twice
yield 1
yield 2
end
twice do |i|
puts i
end
我想知道的是我们是否可以手动调用该函数,以便第一次调用给出1
然后我们做其他事情,然后下一个调用给出2
.
我尝试(只是猜测)各种事情,puts twice()
但无济于事。有什么办法可以做到这一点?
以文档中的这个例子为例,我们可以发送一个yield
从函数接收值的块。
def twice
yield 1
yield 2
end
twice do |i|
puts i
end
我想知道的是我们是否可以手动调用该函数,以便第一次调用给出1
然后我们做其他事情,然后下一个调用给出2
.
我尝试(只是猜测)各种事情,puts twice()
但无济于事。有什么办法可以做到这一点?
您可以使用 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)。但请注意,这有点慢,至少比使用迭代器或常规的非捕获块调用慢得多。