我正在阅读 "Pickaxe" ruby book我遇到了这个例子:
def meth_three
100.times do |num|
square = num*num
return num, square if square > 1000
end
end
如果您在 irb 中调用 meth_three
,它会返回 1 到 100 之间第一个具有 square > 1000
的整数:
meth_three # => [32, 1024]
我的问题是,times
方法如何知道如何遍历 1..100 之间的每个整数以作为参数传递给 |num|
参数?
最佳答案
在 Ruby 中有许多不同的迭代方式。
这是递归实现的一种可能方式:
class Integer
def times(&blk)
return enum_for(__callee__) unless block_given?
return self unless positive?
pred.times(&blk)
yield pred
end
end
或者,使用 Range#each
:
class Integer
def times(&blk)
return enum_for(__callee__) unless block_given?
return self unless positive?
(0...self).each(&blk)
self
end
end
或者,用一个循环:
class Integer
def times
return enum_for(__callee__) unless block_given?
return self unless positive?
i = -1
yield i while (i += 1) < self
self
end
end
还有一个尾递归实现,只是为了好玩:
class Integer
def times(&blk)
return enum_for(__callee__) unless block_given?
return self unless positive?
__times_rec(0, &blk)
self
end
private def __times_rec(i, &blk)
return unless i < self
yield i
__times_rec(i.succ, &blk)
end
end
这是实际 Ruby 实现的实际代码(core/integer.rb
来自Rubinius):
def times return to_enum(:times) { self } unless block_given? i = 0 while i < self yield i i += 1 end self end
TruffleRuby也使用完全相同的代码(参见 src/main/ruby/truffleruby/core/integer.rb
), JRuby 也是如此(参见 core/src/main/ruby/jruby/ruby_implementations/Integer/times.rb
)
这是来自真实 Ruby 实现的另一个真实示例(opal/corelib/number.rb
来自 Opal):
def times(&block) return enum_for(:times) { self } unless block %x{ for (var i = 0; i < self; i++) { block(i); } } self end
如您所见,可以通过多种方式在 Ruby 中编写循环。
关于Ruby .times 方法调用一个整数。它如何知道将每个整数作为 block 中的参数进行迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63018797/