在编程中,我们经常需要逐个遍历值列表。例如,我们可能想打印集合(数组、哈希等)中的每个项目,或在范围中添加数字。
Ruby 提供了两种主要方法来实现此目的:
for
循环each
循环
这两种循环都用于遍历(迭代)集合或范围中的每个项。
让我们逐一探索它们,并看看它们是如何相关的,从 for 循环开始。
Ruby for 循环
for
循环用于迭代范围或集合(如数组或哈希),一次一个。其语法是:
for variable in collection
# Code to execute
end
这里,
collection
- 一个值范围,或一个值集合,如数组或哈希。variable
- 一个占位符,在每次迭代中,它会获取 `collection` 中每个元素的值。
工作原理如下:
for
循环迭代 `collection` 的元素。- 在每次迭代中,`variable` 获取当前 `collection` 元素的值。在下一次迭代中,它会被重新赋值为下一个元素。
- 一旦所有元素都迭代完毕,循环就会结束。
注意: 许多 Ruby 程序员在迭代集合时更喜欢使用 `each` 循环而不是 `for` 循环。
示例 1:带有范围的 Ruby for 循环
for num in 4..6
puts num
end
输出
4 5 6
在这里,`for` 循环迭代范围 `4..6`。因此,循环会运行三次,分别处理数字 **4**、**5** 和 **6**。
在循环的每次迭代中,变量 `num` 的值从 4 变为 6,然后打印到屏幕上。工作原理如下:
循环迭代 | num 的值 |
---|---|
第一次 | 4 |
第二次 | 5 |
第三次 | 6 |
示例 2:带有数组的 Ruby for 循环
people = ["Bob", "Alex", "Sharon", "Cassie"]
for person in people
puts person
end
输出
Bob Alex Sharon Cassie
在这里,`for` 循环迭代 `people` 数组。在循环的每次迭代中,变量 `person` 获取数组的相应元素。工作原理如下:
循环迭代 | person 的值 |
---|---|
1 | "Bob" |
2 | "Alex" |
3 | "Sharon" |
4 | "Cassie" |
示例 3:带有哈希的 Ruby for 循环
# Create a hash named 'person'
# "name", "age", and "city" are keys
# "Alice", 30, and "Paris" are the corresponding values
person = { "name" => "Alice", "age" => 30, "city" => "Paris" }
for key, value in person
puts "#{key}: #{value}"
end
输出
name: Alice age: 30 city: Paris
在这个例子中,我们创建了一个名为 `person` 的哈希。然后,我们使用 `for` 循环迭代该哈希。
在循环的每次迭代中,循环的 `key` 和 `value` 变量会获取哈希中的一个键值对。工作原理如下:
循环迭代 | key | value (值) |
---|---|---|
1 | "name" |
"Alice" |
2 | "age" |
30 |
3 | "city" |
"Paris" |
Ruby each 循环
each
循环是迭代集合的另一种方式。由于其可读性,Ruby 开发人员更倾向于使用它而不是 for 循环。其语法是:
collection.each do |item|
# Code using item
end
这里,
collection
- 一个值集合,如数组或哈希。item
- 一个占位符,在每次迭代中,它会获取 `collection` 中每个元素的值。
示例 4:带有范围的 Ruby each 循环
(4..6).each do |num|
puts num
end
输出
4 5 6
在这里,`each` 循环迭代范围 `4..6`。因此,循环会运行三次,分别处理数字 **4**、**5** 和 **6**。
在循环的每次迭代中,变量 `num` 的值从 4 变为 6,然后打印到屏幕上。工作原理如下:
循环迭代 | num 的值 |
---|---|
第一次 | 4 |
第二次 | 5 |
第三次 | 6 |
示例 5:带有数组的 Ruby each 循环
people = ["Bob", "Alex", "Sharon", "Cassie"]
people.each do |person|
puts person
end
输出
Bob Alex Sharon Cassie
在这里,`each` 循环对 `people` 数组中的每个项目运行一次。
在每次迭代中,`person` 变量获取 `people` 数组中的单个元素,这与我们的 `for` 循环示例的工作方式类似。
循环迭代 | person 的值 |
---|---|
1 | "Bob" |
2 | "Alex" |
3 | "Sharon" |
4 | "Cassie" |
示例 6:带有哈希的 Ruby each 循环
# Create a hash named 'person'
# "name", "age", and "city" are keys
# "Alice", 30, and "Paris" are the corresponding values
person = { "name" => "Alice", "age" => 30, "city" => "Paris" }
person.each do |key, value|
puts "#{key}: #{value}"
end
输出
name: Alice age: 30 city: Paris
在这里,`each` 循环对 `person` 哈希中的每个项目运行一次。
在每次迭代中,循环的 `key` 和 `value` 变量会获取哈希中的一个键值对。工作原理如下:
循环迭代 | key | value (值) |
---|---|---|
1 | "name" |
"Alice" |
2 | "age" |
30 |
3 | "city" |
"Paris" |
常见问题
在 Ruby 中,`each` 循环的单行语法使用花括号 `{}` 而不是 `do...end`。
collection.each { |item| # code using item }
示例
# With range
(1..3).each { |i| puts i }
# With array
[4, 5, 6].each { |i| puts i }
my_hash = { "name" => "Revan", "age" => 40 }
# With hash
my_hash.each { |key, value| puts "#{key}: #{value}" }
输出
1 2 3 4 5 6 name: Revan age: 40
在 Ruby 中,`for` 循环在内部是基于 `each` 方法构建的。因此,当你编写 `for` 循环时,Ruby 实际上是在后台调用 `each`。
因此,这两种循环几乎相同。但是,这两种循环在变量作用域方面有所不同:
for
循环的变量属于与循环所在位置相同的范围。换句话说,您可以在循环外部使用该变量。each
循环的变量仅属于循环内部,不能在循环外部使用。
如前一个 FAQ 中所述,您可以在 `for` 循环外部使用 `for` 循环变量,但不能对 `each` 循环做同样的事情。
示例:for 循环的作用域
for i in 1..3
puts "i = #{i}"
end
# Valid: Using i outside the for loop
puts "i = #{i}"
输出
i = 1 i = 2 i = 3 i = 3
在这里,我们可以在 `for` 循环外部访问 `i` 变量,因为 `for` 循环的作用域与编写循环的位置相同。
示例:each 循环的作用域
(1..3).each do |i|
puts "i = #{i}"
end
# Invalid: Using i outside the each loop
puts "i = #{i}"
输出
i = 1 i = 2 i = 3 main.rb:6:in '<main>': undefined local variable or method 'i' for main (NameError)
正如你所见,当我们尝试在 `each` 循环外部访问 `i` 变量时,会得到一个 `NameError`。
这是因为 `i` 变量是传递给 `each` 方法的块的局部变量。在块外部无法访问它。
换句话说,`each` 循环有自己的作用域(与 `for` 循环不同)。