• ruby迭代器iterator和枚举器Enumerator


    编写自定义的迭代器

    The defining feature of an iterator method is that it invokes a block of code associated
    with the method invocation. You do this with the yield statement. The following
    method is a trivial iterator that just invokes its block twice:
    def twice
     yield
      yield
    end

    To pass argument values to the block, follow the yield statement with a comma separated
    list of expressions. As with method invocation, the argument values may
    optionally be enclosed in parentheses. The following simple iterator shows a use of
    yield:

    def sequence(n,m,c)
        i=0
        while(i<n)
            yield m*i+c
            i+=1
        end
    end
    sequence(3,5,1) { |y| puts y}

    下面是ruby迭代器的另一个例子,它传递两个实参给相关联的代码块,值得注意的是,这个迭代器实现在内部使用了另一个迭代器:

    def circle(r,n)
    n.times do |i| # Notice that this method is implemented with a block
        angle = Math::PI * 2 * i / n
        yield r*Math.cos(angle), r*Math.sin(angle)
    end
    end
    # This invocation of the iterator prints:
    # (1.00, 0.00) (0.00, 1.00) (-1.00, 0.00) (-0.00, -1.00)

    使用yield关键字的确很像调用一个方法,围绕参数的圆括号是可选的,但是,他和方法调用的不同之处在于不能在yield表达式后面接代码块,你不能将一个代码块传递给另一个代码块。

    如果一个方法在调用时没有相关联的代码块,那么在定义该方法时使用yield就是错误的,因为在这种情况下,将没有什么可以作为yield的目标。有时候你希望编写这样一个方法:当有相关联的代码块时就使用yield,否则将采取一些默认行为(而不是抛出一个错误)。为了做到这一点,你可以使用block_given?方法判断是否在调用该方法时带有一个代码块。block_given?及它的同义词iterator?都是Kernel的方法,因此他们表现的像全局函数一样。

    # Return an array with n elements of the form m*i+c
    # If a block is given, also yield each element to the block
    def sequence(n, m, c)
       i, s = 0, [] # Initialize variables
      while(i < n) # Loop n times
        y = m*i + c # Compute value
       yield y if block_given? # Yield, if block
       s << y # Store the value
      i += 1
    end
    s # Return the array of values
    end

    sequence(3,5,1) { |y| puts y}

    s= sequence(3,5,1)
    s.each { |x| print x}

    一个枚举器必须是一个Enumerable对象,其目的在于枚举其他的对象。

    range

    A..Z 范围提供了to_a,可以转成数组

    ('A'..'Z').to_a.each{|letter| print letter}

    检验是否属于某个范围

    puts ('A'..'Z').include?('r')

    还可以把范围当做数组的索引,一次选择多个元素


    a=[2,4,6,8,10]
    puts a[1..3]

    参考:《ruby programming》

  • 相关阅读:
    linux 服务器---FastDFS分布式文件服务器配置
    JFinal getModel方法(从页面表单中获取Model对象)+数据库存储问题
    实现Callable接口。带返回值的线程
    Spring 自动化装配Bean
    Spring--基于代理类ProxyFactoryBean的AOP实现
    Jfinal中的validator理解/详解
    Jfinal中的文件上传
    HotSpot学习(二):虚拟机的启动过程源码解析
    HotSpot学习(一):编译、启动与调试
    Netty的对象池
  • 原文地址:https://www.cnblogs.com/youxin/p/3824251.html
Copyright © 2020-2023  润新知