ruby迭代器iterator和枚举器Enumerator
2014-07-04 14:00 youxin 阅读(1049) 评论(0) 编辑 收藏 举报
编写自定义的迭代器
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》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2013-07-04 asp.net插入sql server 中文乱码问题解决方案
2012-07-04 转:中国互联网十五年的22个创新模式
2012-07-04 保罗·格雷厄姆(Paul Graham
2012-07-04 转:二进制、八进制、十进制、十六进制之间转换