我正在玩弄Ruby以学习语言。目前,我正试图围绕纤维的概念。根据{{3}},它们经常用于创建(无限)外部枚举器。另一方面,这似乎与所谓的显式枚举器的概念重叠。
说,我想写一个触发连续素数的代码片段(是的,以下算法的运行时为O(可怕))。我可以通过使用光纤来实现它:
prime_fiber = Fiber.new do
primes = [2]
Fiber.yield 2
current = 1
loop do
current += 2
unless primes.find {|value| (current % value) == 0}
Fiber.yield current
primes << current
end
end
end
ARGV[0].to_i.times {print "#{prime_fiber.resume}, "}
这不会自己发出枚举器对象,尽管创建一个枚举对象并不困难。相反,我也可以使用一个显式定义的枚举器,它具有已经是枚举器对象的额外好处:
prime_enum = Enumerator.new do |yielder|
primes = [2]
yielder.yield 2
current = 1
loop do
current += 2
unless primes.find {|value| (current % value) == 0}
yielder.yield current
primes << current
end
end
end
ARGV[0].to_i.times {print "#{prime_enum.next}, "}
# I could also write:
# p prime_enum.first(ARGV[0].to_i)
这两种方法都允许我实现某种协同例程,它们似乎可以互换。那么我什么时候比较喜欢一个呢?有一些共同商定的做法吗?我觉得很难把所有这些成语都记在脑子里,所以如果这被认为是一个愚蠢的问题,我会提前道歉。
答案 0 :(得分:1)
我会使用Enumerator
,如果您的序列是有限的,它允许您使用take
,take_while
,甚至each
。虽然Fiber
是为轻量级并发而设计的,但作为枚举器非常有限。
prime_enum.take(ARGV[0].to_i).each { |x| puts x }
或
prime_enum.take_while { |x| x < ARGV[0].to_i }.each { |x| puts x }