Ruby 循环
Ruby 循环和迭代器:重复执行操作
Section titled “Ruby 循环和迭代器:重复执行操作”循环是基本的控制结构,允许你多次执行一段代码。Ruby 提供了传统的循环关键字,以及更符合 Ruby 习惯的强大迭代器方法。
迭代器(惯用的 Ruby 方式):
Section titled “迭代器(惯用的 Ruby 方式):”Ruby 开发者通常更喜欢使用集合(如 Array 和 Hash)和其他对象提供的迭代器方法,而不是传统的循环结构。迭代器简洁、富有表现力,并且通常能更好地管理作用域(scope)。
each 迭代器:
each 迭代器是最常用的迭代器之一。它遍历集合中的每个元素。
#!/usr/bin/ruby
fruits = ["apple", "banana", "cherry"]
fruits.each do |fruit| puts "I love #{fruit}s!"end
# Short block syntax:(1..3).each { |number| puts "Number: #{number}" }输出:
I love apples!I love bananas!I love cherrys!Number: 1Number: 2Number: 3times 迭代器:
执行代码块指定的次数。
#!/usr/bin/ruby
3.times do |i| puts "Iteration number #{i + 1}"end输出:
Iteration number 1Iteration number 2Iteration number 3其他常用迭代器:map, select, reject, upto, downto 等。它们提供了强大的方式来转换和过滤集合。(更多关于 map, select 等的内容请参阅 Array 章节)
传统循环结构:
Section titled “传统循环结构:”虽然迭代器通常更受欢迎,但 Ruby 也支持传统的循环关键字。
Ruby while 语句:
Section titled “Ruby while 语句:”只要条件为真,就执行代码。
语法:
while condition [do] # code to executeend示例:
#!/usr/bin/ruby
count = 0limit = 3
while count < limit do puts "Inside the while loop, count = #{count}" count += 1end输出:
Inside the while loop, count = 0Inside the while loop, count = 1Inside the while loop, count = 2Ruby while 修饰符(单行 while):
Section titled “Ruby while 修饰符(单行 while):”语法:
# code to execute while condition
# or more commonly for one-liners:begin # codeend while condition示例:
#!/usr/bin/ruby
value = 0begin puts "Value is #{value}" value += 1end while value < 3输出:
Value is 0Value is 1Value is 2Ruby until 语句:
Section titled “Ruby until 语句:”只要条件为假(即直到条件变为真),就执行代码。
语法:
until condition [do] # code to executeend示例:
#!/usr/bin/ruby
counter = 5
until counter <= 0 do puts "Inside the until loop, counter = #{counter}" counter -= 1end输出:
Inside the until loop, counter = 5Inside the until loop, counter = 4Inside the until loop, counter = 3Inside the until loop, counter = 2Inside the until loop, counter = 1Ruby until 修饰符(单行 until):
Section titled “Ruby until 修饰符(单行 until):”语法:
# code to execute until condition
begin # codeend until condition示例:
#!/usr/bin/ruby
stock = 3begin puts "Processing item, stock remaining: #{stock}" stock -= 1end until stock == 0输出:
Processing item, stock remaining: 3Processing item, stock remaining: 2Processing item, stock remaining: 1Ruby for...in 语句:
Section titled “Ruby for...in 语句:”遍历集合中的元素(或任何响应 each 方法的对象)。
语法:
for loop_variable in expression [do] # code to executeend示例:
#!/usr/bin/ruby
for i in 0..2 # Iterates through the range 0 to 2 (inclusive) puts "Value of local variable is #{i}"end
colors = ["red", "green", "blue"]for color in colors puts "Color: #{color}"end输出:
Value of local variable is 0Value of local variable is 1Value of local variable is 2Color: redColor: greenColor: blue注意:for...in 循环大致等同于 (expression).each do |loop_variable| ... end。然而,一个关键区别是 for...in 不会为 loop_variable 创建新的作用域,而 each 配合代码块会创建。出于这个原因以及保持代码一致性,在现代 Ruby 中通常更推荐使用 each。
循环控制语句:
Section titled “循环控制语句:”Ruby 提供了控制循环流程的语句:
break 语句:
立即终止最内层的循环。
#!/usr/bin/ruby
(0..4).each do |i| if i == 3 then puts "Breaking at i = #{i}" break end puts "Value of i is #{i}"end输出:
Value of i is 0Value of i is 1Value of i is 2Breaking at i = 3next 语句:
跳过当前迭代的剩余部分,继续最内层循环的下一次迭代。
#!/usr/bin/ruby
(0..4).each do |i| if i == 2 then puts "Skipping i = #{i}" next end puts "Value of i is #{i}"end输出:
Value of i is 0Value of i is 1Skipping i = 2Value of i is 3Value of i is 4redo 语句:
从头重新开始最内层循环的当前迭代,但不重新评估循环的条件(如果有)。
#!/usr/bin/ruby
attempts = 0(0..2).each do |i| puts "Attempting task for i = #{i}, attempt ##{attempts + 1}" if i == 1 && attempts < 2 then attempts += 1 puts "Redoing for i = #{i}" redo # Restarts this iteration (for i = 1) end puts "Completed task for i = #{i}" attempts = 0 # Reset for next iend输出:
Attempting task for i = 0, attempt #1Completed task for i = 0Attempting task for i = 1, attempt #1Redoing for i = 1Attempting task for i = 1, attempt #2Redoing for i = 1Attempting task for i = 1, attempt #3Completed task for i = 1Attempting task for i = 2, attempt #1Completed task for i = 2注意:如果不小心使用,redo 很容易导致死循环。它不如 break 或 next 常用。
retry 语句:
retry 语句主要用于 rescue 代码块中,以重新执行发生异常的整个 begin...end 代码块。在循环内部直接使用它(不在 rescue 子句中)是罕见的,并且可能令人困惑,因为它通常会从最开始重新启动整个循环或迭代器。
retry 在 rescue 子句中的示例(其常见用法):
#!/usr/bin/ruby
retries_left = 2begin puts "Attempting operation..." # Simulate an error sometimes raise "Simulated network error" if rand(3) == 0 && retries_left > 0 puts "Operation successful!"rescue => e puts "Error: #{e.message}" if retries_left > 0 retries_left -= 1 puts "Retrying... (#{retries_left} retries left)" retry # Restart the begin block else puts "No more retries. Operation failed." endend实际应用:
循环和迭代器在各种场景下都广泛使用:处理用户输入、逐行读取文件、迭代数据库记录、渲染 UI 组件、重复执行计算等等。选择合适的循环结构(通常是 each 或 map 等迭代器)可以使你的 Ruby 代码更具可读性和效率。