如何在Ruby中编写switch语句?


当前回答

你可以用更自然的方式这样做,

case expression
when condtion1
   function
when condition2
   function
else
   function
end

其他回答

多值时和无值情况:

print "Enter your grade: "
grade = gets.chomp
case grade
when "A", "B"
  puts 'You pretty smart!'
when "C", "D"
  puts 'You pretty dumb!!'
else
  puts "You can't even use a computer!"
end

这里有一个正则表达式解决方案:

print "Enter a string: "
some_string = gets.chomp
case
when some_string.match(/\d/)
  puts 'String has numbers'
when some_string.match(/[a-zA-Z]/)
  puts 'String has letters'
else
  puts 'String has no numbers or letters'
end

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

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的行为有点意外。这是因为它使用了==运算符。

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

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

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

Ruby在2.7中引入了模式匹配

这是一个超级强大的功能

它也使用case,但有另一种语法

还有查找模式功能

users =
  { users:
    [
      { user: 'user', email: 'user@user.com' },
      { user: 'admin', email: 'admin@admin.com' },
    ]
  }

case users
in users: [*, { user:, email: /admin/ => admin_email }, *]
  puts admin_email
else
  puts "No admin"
end

# will print admin@admin.com

与通常情况不同,如果条件不匹配,将抛出NoMatchingPatternError。所以你可能不得不使用else分支

在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子句附加多个&&表达式。