题 如何在Ruby中编写switch语句?


如何在Ruby中编写switch语句?


1833
2018-06-04 01:18


起源




答案:


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 用一个 break。您还可以在一个中指定多个匹配项 when 条款喜欢 when "foo", "bar"


2306
2018-06-04 01:22



railsless.blogspot.com/2011/01/... - Pankaj
你也可以对传递的参数做正则表达式:when / thisisregex / 下一行  将“这是找到的匹配号1#{$ 1}”结束 - Automatico
另外值得注意的是,您可以通过放置代码来缩短代码 when 和 return 声明在同一行: when "foo" then "bar" - Alexander


case...when 在处理类时表现得有些意外。这是因为它使用了 === 运营商。

该运算符按预期使用文字,但不使用类:

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

这意味着如果你想做一个 case ... when 在一个对象的类上,这将不起作用:

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')
end

将打印“它不是一个字符串”。

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

Fixnum === 1 # => true

简而言之,上面的代码可以通过删除来修复 .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')
end

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


397
2018-04-17 15:20



obj ='hello'; case obj;当'你好'然后把“它是你好”结束 - v Sugumar


这是由 案件 在Ruby中。另见 这篇关于维基百科的文章

引:

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

在第123页(我正在使用Kindle)的 Ruby编程Lanugage (第1版,O'Reilly),它说 then 关键字跟随 when 子句可以用换行符或分号替换(就像在 if then else 句法)。 (Ruby 1.8也允许使用冒号代替 then...但是Ruby 1.9中不再允许这种语法。)


187
2018-06-04 01:20



when (-1.0/0.0)..-1 then "Epic fail" - Andrew Grimm
这是我使用的答案,因为我根据案例开关的结果定义了一个变量。而不是说 type = #{score} 每一行,我都可以简单地复制你所做的。更优雅我也更喜欢单线(如果可能的话) - onebree


    情况......当

添加更多示例 查克的回答

带参数:

case a
when 1
  puts "Single value"
when 2, 3
  puts "One of comma-separated values"
when 4..6
  puts "One of 4, 5, 6"
when 7...9
  puts "One of 7, 8, but not 9"
else
  puts "Any other thing"
end

没有参数:

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

请注意 问题 基基托警告说。


88
2017-07-05 13:19



谢谢,这对于在一行上有多个选项很有帮助。我一直在尝试使用 or - sixty4bit


许多编程语言,特别是那些从C派生的语言,都支持所谓的语言 切换秋天。我正在寻找在Ruby中做同样事情的最佳方法,并认为它可能对其他人有用:

在类C语言中,fallthrough通常如下所示:

switch (expression) {
    case 'a':
    case 'b':
    case 'c':
        // Do something for a, b or c
        break;
    case 'd':
    case 'e':
        // Do something else for d or e
        break;
}

在Ruby中,可以通过以下方式实现:

case expression
when 'a', 'b', 'c'
  # Do something for a, b or c
when 'd', 'e'
  # Do something else for d or e
end

这不是严格等同的,因为它不可能让 'a' 在落到之前执行一段代码 'b' 要么 'c',但在大多数情况下,我发现它相似,足以以同样的方式有用。


64
2017-12-07 12:11





在Ruby 2.0中,您还可以使用lambdas case 声明如下:

is_even = ->(x) { x % 2 == 0 }

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

您还可以使用带有自定义的Struct轻松创建自己的比较器 ===

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

(例子取自“proc可以与Ruby 2.0中的case语句一起使用吗?”。)

或者,完整的课程:

class Vehicle
  def ===(another_vehicle)
    self.number_of_wheels == another_vehicle.number_of_wheels
  end
end

four_wheeler = Vehicle.new 4
two_wheeler = Vehicle.new 2

case vehicle
when two_wheeler
  puts 'two wheeler'
when four_wheeler
  puts 'four wheeler'
end

(例子取自“Ruby案例陈述如何运作以及您可以用它做什么”。)


63
2017-08-01 00:04





您可以使用正则表达式,例如查找字符串类型:

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

Ruby的 case 将使用相等操作数 === 为此(感谢@JimDeville)。更多信息请参见“Ruby运算符“。这也可以使用@mmdemirbas示例(不带参数)来完成,只有这种方法对于这些类型的情况更清晰。


47
2017-10-16 12:17





如果您渴望知道如何在Ruby switch案例中使用OR条件:

所以,在一个 case 声明,a , 相当于 || 在一个 if 声明。

case car
   when 'Maruti', 'Hyundai'
      # Code here
end

您可以使用Ruby案例语句执行许多其他操作


29
2017-07-03 06:46





它被称为 case 它的工作方式与您期望的一样,还有更多有趣的东西 === 它实现了测试。

case 5
  when 5
    puts 'yes'
  else
    puts 'else'
end

现在为了一些乐趣:

case 5 # every selector below would fire (if first)
  when 3..7    # OK, this is nice
  when 3,4,5,6 # also nice
  when Fixnum  # or
  when Integer # or
  when Numeric # or
  when Comparable # (?!) or
  when Object  # (duhh) or
  when Kernel  # (?!) or
  when BasicObject # (enough already)
    ...
end

事实证明,您也可以替换任意的if / else链(即,即使测试不涉及公共变量) case 通过省略初始 case 参数,只需编写表达式,第一个匹配就是你想要的。

case
  when x.nil?
    ...
  when (x.match /'^fn'/)
    ...
  when (x.include? 'substring')
    ...
  when x.gsub('o', 'z') == 'fnzrq'
    ...
  when Time.now.tuesday?
    ...
end

24
2018-02-05 20:40





以来 switch case 总是返回一个对象,我们可以直接打印它的结果:

puts case a
     when 0
        "It's zero"
     when 1
        "It's one"
     end

18
2017-11-05 07:29