9

在 Ruby 中,使用 for 循环是不好的风格。这是普遍理解的。向我推荐的风格指南:(https://github.com/bbatsov/ruby-style-guide#source-code-layout)说:

“永远不要使用 for,除非你确切地知道为什么。大多数时候应该使用迭代器。for 是根据每个来实现的(所以你要添加一个间接级别),但是有一个转折 - for 没有引入一个新的范围(与每个不同)和在其块中定义的变量将在其外部可见。”

给出的例子是:

arr = [1, 2, 3]

#bad
for elem in arr do
  puts elem
end

# good
arr.each { |elem| puts elem }

我进行了研究,但找不到关于如何模拟 for 循环的解释,该循环提供了一个迭代值,我可以将其传递给位置或执行算术运算。例如,我将替换为:

for i in 0...size do
  puts array1[i]
  puts array2[size-1 - i]
  puts i % 2
end

如果它是一个数组很容易,但我经常需要当前位置用于其他目的。我缺少一个简单的解决方案,或者需要for的情况。此外,我听到人们谈论for好像它从来不需要。那么他们对此的解决方案是什么?

可以改进吗?如果有解决方案,解决方案是什么?谢谢。

4

2 回答 2

10

如果要遍历集合跟踪索引,请使用each_with_index

fields = ["name", "age", "height"]

fields.each_with_index do |field,i|
  puts "#{i}. #{field}" # 0. name, 1. age, 2. height
end

您的for i in 0...size示例变为:

array1.each_with_index do |item, i|
  puts item
  puts array2[size-1 - i]
  puts i % 2
end
于 2013-08-13T17:06:43.043 回答
3

别忘了你也可以做这样很酷的事情

fields = ["name", "age", "height"]

def output name, idx
  puts "#{idx}. #{name}"
end

fields.each_with_index &method(:output)

输出

0. name
1. age
2. height

您也可以将此技术用作类或实例方法

class Printer
  def self.output data
    puts "raw: #{data}"
  end
end

class Kanon < Printer
  def initialize prefix
    @prefix = prefix
  end
  def output data
    puts "#{@prefix}: #{data}"
  end
end

def print printer, data
  # separating the block from `each` allows
  # you to do interesting things
  data.each &printer.method(:output)
end

使用类方法的示例

print Printer, ["a", "b", "c"]
# raw: a
# raw: b
# raw: c

使用实例方法的示例

kanon = Kanon.new "kanon prints pretty"
print kanon, ["a", "b", "c"]
# kanon prints pretty: a
# kanon prints pretty: b
# kanon prints pretty: c
于 2013-08-13T17:20:01.597 回答