Ruby中如何编写switch语句

Ruby中如何编写switch语句

技术背景

在许多编程语言中,switch 语句是一种常用的条件控制结构,用于根据不同的条件执行不同的代码块。然而,在 Ruby 语言中并没有传统意义上的 switch 语句,而是使用 case 表达式来实现类似的功能。

实现步骤

基本的 case 表达式

在 Ruby 中,case 表达式的基本语法如下:

1
2
3
4
5
6
7
8
case x
when 条件1
# 代码块1
when 条件2
# 代码块2
else
# 默认代码块
end

其中,x 是要进行判断的值,when 后面跟着不同的条件,当 x 满足某个 when 后面的条件时,就会执行该 when 对应的代码块。如果所有条件都不满足,则执行 else 后面的代码块。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end

无参数的 case 表达式

还可以省略 case 后面的参数,直接在 when 后面写条件表达式:

1
2
3
4
5
6
7
8
case
when b < 3
puts "Little than 3"
when b == 3
puts "Equal to 3"
when (1..10) === b
puts "Something in closed range of [1..10]"
end

使用 lambda 或自定义比较器

在 Ruby 2.0 及以后的版本中,还可以在 case 语句中使用 lambda 或自定义比较器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
is_even = ->(x) { x % 2 == 0 }

case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

Moddable = Struct.new(:n) do
def ===(numeric)
numeric % n == 0
end
end

mod4 = Moddable.new(4)
mod3 = Moddable.new(3)

case number
when mod4 then puts 'multiple of 4'
when mod3 then puts 'multiple of 3'
end

使用正则表达式

可以使用正则表达式来匹配字符串:

1
2
3
4
5
6
7
8
9
10
case foo
when /^(true|false)$/
puts "Given string is boolean"
when /^[0-9]+$/
puts "Given string is integer"
when /^[0-9\.]+$/
puts "Given string is float"
else
puts "Given string is probably string"
end

核心代码

基本 case 表达式

1
2
3
4
5
6
7
8
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end

无参数 case 表达式

1
2
3
4
5
6
7
8
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end

使用 lambda 的 case 表达式

1
2
3
4
5
6
is_even = ->(x) { x % 2 == 0 }
case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

使用正则表达式的 case 表达式

1
2
3
4
5
6
7
8
9
10
case foo
when /^(true|false)$/
puts "Given string is boolean"
when /^[0-9]+$/
puts "Given string is integer"
when /^[0-9\.]+$/
puts "Given string is float"
else
puts "Given string is probably string"
end

最佳实践

避免使用过长的 case 语句

如果 case 语句中的 when 条件过多,可以考虑使用哈希表来替代,以提高代码的可读性和可维护性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}

def menu1
puts 'menu 1'
end

def menu2
puts 'menu 2'
end

def menu3
puts 'menu3'
end

selected_menu = :a
send(menu[selected_menu])

注意 === 运算符的使用

case/when 语句中,Ruby 使用 === 运算符进行比较。不同的类对 === 运算符有不同的实现,需要注意其行为。例如,在比较对象的类时,要确保正确使用 === 运算符:

1
2
3
4
5
6
7
8
9
obj = 'hello'
case obj
when String
print('It is a string')
when Fixnum
print('It is a number')
else
print('It is not a string or number')
end

常见问题

case 语句中使用类进行比较时的问题

case 语句中直接使用对象的类进行比较可能会得到意外的结果,因为 === 运算符在处理类时的行为与预期不同。可以通过直接使用对象而不是对象的类来解决这个问题。

忘记 else 语句

如果 case 语句中没有 else 语句,当所有 when 条件都不满足时,不会执行任何代码。在需要处理默认情况时,应该添加 else 语句。


Ruby中如何编写switch语句
https://119291.xyz/posts/how-to-write-a-switch-statement-in-ruby/
作者
ww
发布于
2025年5月16日
许可协议