ZetCode

Ruby 中的 in 关键字

最后修改日期:2025 年 4 月 27 日

本教程解释了如何使用 Ruby 的 in 关键字进行模式匹配。它在 Ruby 2.7 中引入,提供了强大的模式匹配功能。

in 关键字检查一个值是否匹配一个模式。它与 case 语句和独立表达式一起使用。它可以解构复杂的对象。

模式匹配简化了复杂数据结构的条件逻辑。in 操作符使代码更具可读性和可维护性。它在现代 Ruby 代码中被广泛使用。

基本 in 关键字示例

这个简单的例子演示了 in 关键字与 case 语句的基本用法。它匹配不同的值模式。

basic_in.rb
value = 42

case value
in 0
  puts "Zero"
in 1..50
  puts "Between 1 and 50"
in 51..100
  puts "Between 51 and 100"
else
  puts "Something else"
end

in 关键字检查 value 是否匹配每个模式。当找到匹配项时,相应的块会执行。范围自然地工作。

数组模式匹配

in 关键字可以解构数组。本例展示了如何匹配带变量绑定的数组模式。

array_matching.rb
data = [1, 2, 3]

case data
in [a, b, c]
  puts "Three elements: #{a}, #{b}, #{c}"
in [1, *rest]
  puts "Starts with 1, rest: #{rest}"
else
  puts "No match"
end

第一个模式匹配任何 3 元素数组,并将元素绑定到变量。第二个模式匹配以 1 开头的数组。splat 操作符捕获其余元素。

哈希模式匹配

哈希模式的工作方式与数组类似。本例演示了如何匹配哈希键并提取值。

hash_matching.rb
person = {name: "John", age: 30, city: "New York"}

case person
in {name: "John", age:}
  puts "John is #{age} years old"
in {name:, city:}
  puts "#{name} lives in #{city}"
else
  puts "No match"
end

第一个模式匹配 :name 为 "John" 且年龄任意的哈希。第二个模式从包含这些键的任何哈希中提取姓名和城市。

独立 in 表达式

in 关键字可以在 case 语句之外使用。本例展示了它在匹配模式时的布尔返回值。

standalone_in.rb
data = [1, 2, 3]

if data in [first, *]
  puts "First element is #{first}"
end

puts "Match!" if {a: 1, b: 2} in {a:}

独立 in 在模式匹配时返回 true。它会在当前作用域中绑定变量。splat 操作符会忽略其余元素。

带守卫的模式匹配

模式可以使用 if 守卫包含附加条件。这为匹配增加了更多特异性。

guards.rb
user = {name: "Alice", age: 25}

case user
in {name:, age:} if age >= 18
  puts "#{name} is an adult"
in {name:, age:}
  puts "#{name} is a minor"
end

守卫条件 if age >= 18 使第一个模式更具体。守卫可以使用任何带有模式变量的布尔表达式。

嵌套模式匹配

模式可以嵌套以匹配复杂的数据结构。本例展示了如何匹配嵌套的数组和哈希。

nested.rb
data = {
  user: {name: "Bob", roles: [:admin, :editor]},
  timestamp: Time.now
}

case data
in {user: {name:, roles: [:admin, *]}, timestamp:}
  puts "#{name} is an admin at #{timestamp}"
in {user: {name:, roles:}, timestamp:}
  puts "#{name} has roles: #{roles.join(', ')}"
end

第一个模式仅在 roles 包含 :admin 时匹配。嵌套模式可以匹配哈希中的数组,反之亦然。变量在每个级别绑定。

替代模式

in 关键字支持使用 | 的替代模式。如果任何一个模式成功,它就会匹配。

alternatives.rb
response = {status: 404, message: "Not Found"}

case response
in {status: 200..299}
  puts "Success"
in {status: 400..499 | 500..599}
  puts "Client or server error"
in {status:}
  puts "Unknown status: #{status}"
end

第二个模式匹配 4xx 或 5xx 状态码。替代模式必须绑定相同的变量。它们提供了简洁的 OR 逻辑。

来源

Ruby 模式匹配文档

本教程通过实际示例介绍了 Ruby 的 in 关键字,展示了数组、哈希和嵌套模式匹配技术。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Ruby 教程