欺骗for迭代器



下面这段代码来自我审查过的一个程序。它计算第n个斐波那契数:

for i in 2..input.to_i
  fibonacci = a + b
  a = b
  b = fibonacci
  i += 1            # <-  This
end

注释行i += 1实际上什么也没做。

i是块参数是正确的吗?即,for语句在功能上是否与(2..input.to_i).each do |i|相同?

i += 1行实际上并不影响迭代器。使用for, eachtimes循环,迭代器是否有可能移动到某个迭代?

首先,这里是你想要的参考:

    for循环语法
  • next报表
  • redo报表
  • Enumerator

:

  1. 说i是块参数是正确的吗?

  2. for没有引入新的变量作用域或使用块。
  3. for语句的功能与(2..input.to_i).each do |i|相同吗?

    for i in ...for执行的地方创建了一个变量i,而each不会这样做(IIRC早期的Ruby版本会这样做)。

  4. 迭代器是否有可能移动到某个迭代?

    您可以像这样跳过或重做单个迭代(也可能在each迭代中):

    wait_until = Time.now + 10
    for i in [1,2,3]
      redo if Time.now < wait_until # actively sleep
      next if i.even?
    end
    

    但是你不能跳到任意位置

    为了更好地控制迭代,您需要一个Enumerator实例。如果不带参数/block调用each,将得到一个枚举数:

    enum = [1,2,3].each
    begin
      while i = enum.next
        puts i
      end
    rescue StopIteration
    end
    # equivalent to
    # [1,2,3].each {|i| puts i }
    

    enum现在响应rewind, peek等(见上面链接的文档)。

for实际上只是each的糖(尝试在不可枚举对象上使用for -它应该抱怨它没有响应每个对象)。它的不同之处在于它不创建块作用域。

each如何实现取决于您调用它的对象(每个对象都是构建所有Enumerable的方法)。在任何情况下,都将使用一系列值调用该块。对生成的块变量重新赋值没有任何作用——在下一次迭代时,i将被设置为下一个值。

你可以用next跳过,也可以用break结束,但就控制迭代而言,这就是它-没有办法说"向前跳转3"

最新更新