好的!以下是关于 Ruby 循环 的详细讲解。Ruby 提供了多种循环结构,用于重复执行代码块。它们灵活且易用,特别适合处理集合数据(如数组、哈希)。我会介绍主要的循环方法,结合中文示例和实际场景,帮助你掌握 Ruby 循环的用法。


1. 基本概念

循环用于重复执行一段代码,直到满足某个条件或遍历完数据。Ruby 的循环结构既有传统形式(如 while),也有 Ruby 特色的迭代器(如 each)。


2. while 循环

语法

当条件为真时,重复执行代码。

while 条件
  # 代码块
end

示例

count = 0
while count < 3
  puts "第 #{count + 1} 次"
  count += 1
end

输出:

第 1 次
第 2 次
第 3 次

单行写法

count = 0
puts "计数:#{count += 1}" while count < 3

输出:

计数:1
计数:2
计数:3

3. until 循环

语法

当条件为假时,重复执行代码(while 的反向版本)。

until 条件
  # 代码块
end

示例

count = 0
until count >= 3
  puts "第 #{count + 1} 次"
  count += 1
end

输出:

第 1 次
第 2 次
第 3 次

单行写法

count = 0
puts "计数:#{count += 1}" until count >= 3

4. for 循环

语法

用于遍历范围或集合。

for 变量 in 集合
  # 代码块
end

示例

for i in 1..3
  puts "第 #{i} 次"
end

输出:

第 1 次
第 2 次
第 3 次

注意

  • for 不常用于数组遍历,更推荐 each
  • 变量作用域会泄漏到外部:
  for i in 1..2
    # do something
  end
  puts i  # 2(仍然可见)

5. each 循环(Ruby 特色)

语法

each 是 Ruby 中最常用的迭代器,用于遍历集合(如数组、哈希、范围)。

集合.each do |元素|
  # 代码块
end

示例:数组

水果 = ["苹果", "香蕉", "橙子"]
水果.each do |fruit|
  puts "我喜欢 #{fruit}"
end

输出:

我喜欢 苹果
我喜欢 香蕉
我喜欢 橙子

示例:哈希

学生 = { 姓名: "张三", 年龄: 20 }
学生.each do |键, 值|
  puts "#{键}:#{值}"
end

输出:

姓名:张三
年龄:20

单行写法

[1, 2, 3].each { |n| puts n * 2 }  # 2, 4, 6

6. times 循环

语法

重复执行指定次数,常用于简单计数循环。

数字.times do |i|
  # 代码块
end

示例

3.times do |i|
  puts "第 #{i + 1} 次"
end

输出:

第 1 次
第 2 次
第 3 次

单行写法

3.times { puts "你好" }  # 你好(3 次)

7. loop 循环

语法

无限循环,除非用 break 退出。

loop do
  # 代码块
end

示例

count = 0
loop do
  puts "计数:#{count}"
  count += 1
  break if count >= 3
end

输出:

计数:0
计数:1
计数:2

8. 控制循环

break

跳出循环:

fruits = ["苹果", "香蕉", "橙子"]
fruits.each do |fruit|
  puts fruit
  break if fruit == "香蕉"
end

输出:

苹果
香蕉

next

跳到下一次迭代:

(1..5).each do |n|
  next if n % 2 == 0  # 跳过偶数
  puts n
end

输出:

1
3
5

redo

重新执行当前迭代:

count = 0
while count < 3
  puts "计数:#{count}"
  count += 1
  redo if count == 2  # 重复 count == 2 这一次
end

输出:

计数:0
计数:1
计数:2
计数:2
计数:3

9. 中文支持示例

Ruby 的循环天然支持中文:

任务 = ["写代码", "开会", "休息"]
任务.each do |task|
  puts "今天要 #{task}"
end

输出:

今天要 写代码
今天要 开会
今天要 休息

10. 实践案例

案例 1:打印九九乘法表

(1..9).each do |i|
  (1..9).each do |j|
    print "#{i} × #{j} = #{i * j}\t"
  end
  puts  # 换行
end

输出(部分):

1 × 1 = 1    1 × 2 = 2   1 × 3 = 3   ...
2 × 1 = 2    2 × 2 = 4   2 × 3 = 6   ...

案例 2:任务清单

class TaskList
  def initialize
    @任务 = []
  end

  def 添加(任务名)
    @任务 << 任务名
  end

  def 显示
    @任务.each_with_index do |task, index|
      puts "#{index + 1}. #{task}"
    end
  end
end

清单 = TaskList.new
清单.添加("买菜")
清单.添加("做饭")
清单.显示

输出:

1. 买菜
2. 做饭

案例 3:倒计时

seconds = 5
while seconds > 0
  puts "倒计时:#{seconds} 秒"
  seconds -= 1
end
puts "时间到!"

输出:

倒计时:5 秒
倒计时:4 秒
倒计时:3 秒
倒计时:2 秒
倒计时:1 秒
时间到!

11. 注意事项

  • 优先级eachtimes 是 Ruby 的首选,优于 forwhile,因为它们更符合 Ruby 的风格。
  • 作用域:块变量(如 |i|)仅在块内有效。
  • 无限循环:使用 loop 时记得加退出条件,避免死循环。

下一步

  • 练习:告诉我你想用哪种循环(whileeach 等),我可以设计一个例子。
  • 问题解答:对循环用法有疑问吗?直接问我!
  • 深入学习:想了解循环与迭代器(如 mapselect)的结合吗?我可以继续讲解。

你现在想做什么?写代码、问问题,还是其他?