如何在Ruby中编写switch语句?


当前回答

$age =  5
case $age
when 0 .. 2
   puts "baby"
when 3 .. 6
   puts "little child"
when 7 .. 12
   puts "child"
when 13 .. 18
   puts "youth"
else
   puts "adult"
end

有关更多信息,请参阅“Ruby-if…else,case,除非”。

其他回答

这是在Ruby中使用case完成的。另请参阅维基百科上的“Switch语句”。

引用:

case n
when 0
  puts 'You typed zero'
when 1, 9
  puts 'n is a perfect square'
when 2
  puts 'n is a prime number'
  puts 'n is an even number'
when 3, 5, 7
  puts 'n is a prime number'
when 4, 6, 8
  puts 'n is an even number'
else
  puts 'Only single-digit numbers are allowed'
end

另一个例子:

score = 70

result = case score
   when 0..40 then "Fail"
   when 41..60 then "Pass"
   when 61..70 then "Pass with Merit"
   when 71..100 then "Pass with Distinction"
   else "Invalid Score"
end

puts result

在我的Kindle上的《Ruby编程语言》(第一版,O'Reilly)第123页左右,它说when子句后面的then关键字可以用换行符或分号替换(就像if-then-else语法中的那样)。(Ruby 1.8也允许用冒号代替then,但Ruby 1.9中不再允许使用这种语法。)

Ruby改用case表达式。

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

Ruby使用==运算符将when子句中的对象与case子句中的目标进行比较。例如,1..5==x,而不是x===1..5。

这就允许出现上述复杂的when子句。范围、类别和所有种类的东西都可以测试,而不仅仅是平等。

与许多其他语言中的switch语句不同,Ruby的case没有中断,因此不需要在每次中断时结束。您还可以在一个when子句中指定多个匹配项,如when“foo”、“bar”。

如果您需要“小于”或“大于”:

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when 7..1.0/0
  "It's equal or greater than 7"
when -1.0/0..0
  "It's equal or less than 0"
end

1.0/0等于Float::INFINITY,因此您可以使用自己喜欢的。

在Ruby 2.6之后,您可以使用Endless Ranges,在Ruby 2.7之后,您还可以使用Beginless Ranges,例如:

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when (7..)
  "It's equal or greater than 7"
when (..0)
  "It's equal or less than 0"
end

在when子句中强调逗号(,)至关重要。它充当if语句的||,也就是说,它在when子句的分隔表达式之间进行OR比较,而不是and比较。参见以下案例陈述:

x = 3
case x
  when 3, x < 2 then 'apple'
  when 3, x > 2 then 'orange'
end
 => "apple"

x不小于2,但返回值为“apple”。为什么?因为x是3,并且由于“,”充当||,所以它不必计算表达式x<2。

您可能认为,要执行AND,可以执行以下操作,但它不起作用:

case x
  when (3 && x < 2) then 'apple'
  when (3 && x > 2) then 'orange'
end
 => nil 

它不起作用,因为(3&&x>2)的计算结果为true,Ruby获取true值,并将其与x进行比较,使用==,这是不正确的,因为x是3。

要进行&&比较,您必须将case视为if/else块:

case
  when x == 3 && x < 2 then 'apple'
  when x == 3 && x > 2 then 'orange'
end

在《Ruby编程语言》一书中,Matz表示后一种形式是简单的(而且很少使用)形式,它只是if/elsif/else的一种替代语法。然而,无论它是否不经常使用,我看不到任何其他方法可以为给定的when子句附加多个&&表达式。

案例当处理类时,when的行为有点意外。这是因为它使用了==运算符。

该运算符与预期的文字一起工作,但与类不同:

1 === 1           # => true
Fixnum === Fixnum # => false

这意味着如果你想做一个案子。。。当在对象的类上时,这将不起作用:

obj = 'hello'
case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string or number')
end

将打印“它不是字符串或数字”。

幸运的是,这很容易解决。已定义==运算符,如果将其与类一起使用,并将该类的实例作为第二个操作数提供,则返回true:

Fixnum === 1 # => true

简而言之,可以通过从case obj.class中删除.class来修复上述代码:

obj = 'hello'
case obj  # was case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string or number')
end

我今天在寻找答案的时候遇到了这个问题,这是第一个出现的页面,所以我认为这对其他处于同样情况的人来说很有用。