当前位置:  开发笔记 > 编程语言 > 正文

如何在Ruby中编写switch语句

如何解决《如何在Ruby中编写switch语句》经验,为你挑选了18个好方法。

如何在Ruby中编写switch语句?



1> Chuck..:

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 === xx === 1..5

这允许when如上所示的复杂条款.可以测试范围,类和各种事物而不仅仅是平等.

不像switch其他许多语言的语句,Ruby的case没有落空,所以没有必要结束每when一个break.您还可以在单​​个when子句中指定多个匹配项when "foo", "bar".


你也可以对传递的参数做正则表达式:when/thisisregex/*next line*puts"这是找到的匹配nr.1#{$ 1}"结束
**重要:**与许多其他语言中的`switch`语句不同,Ruby的`case`不具有[** fall-through **](https://en.wikipedia.org/wiki/Switch_statement#Fallthrough),因此,没有必要在每个`when`处以`break`结尾。
同样值得注意的是,您可以通过在同一行上放置`when`和`return`语句来缩短代码:`when“ foo”然后“ bar”`

2> kikito..:

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

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



3> nopole..:

它是用Ruby中的case来完成的.另请参阅Wikipedia上的这篇文章.

引:

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

Ruby Programming Lanugage(第1版,O'Reilly)的第123页(我正在使用Kindle)上,它表示子句case后面的关键字then可以用换行符或分号替换(就像在when语法中一样).(Ruby 1.8也允许冒号代替if then else......但Ruby 1.9中不再允许这种语法.)


`when(-1.0/0.0)..- 1然后"Epic fail"`

4> mmdemirbas..:
情况......当

要向Chuck的答案添加更多示例:

带参数:

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

请注意kikito警告的问题.



5> Robert Kajic..:

许多编程语言,特别是那些从C派生的编程语言,都支持所谓的Switch Fallthrough.我正在寻找在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',但是在大多数情况下我发现它类似于以相同的方式有用.



6> James Lim..:

在Ruby 2.0中,您还可以在case语句中使用lambdas ,如下所示:

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

(示例摘自" 可以在Ruby 2.0中使用案例语句进行处理吗? ".)

或者,完整的课程:

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案例陈述如何工作以及您可以用它做什么 ".)



7> Haris Krajin..:

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

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 Operators ".这也可以使用@mmdemirbas示例(不带参数)来完成,只有这种方法对于这些类型的情况更清晰.



8> Manish Shriv..:

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

因此,在一个case声明中,a ,等同||if声明.

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

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



9> DigitalRoss..:

它被称为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

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

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



10> Alexander..:

根据您的情况,您可能更喜欢使用方法哈希.

如果有一个很长的时间列表,并且每个都有一个具体值要与之比较(而不是间隔),那么声明方法的散列然后从这样的散列调用相关方法会更有效.

# Define the hash
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}

# Define the methods
def menu1
  puts 'menu 1'
end

def menu2
  puts 'menu 2'
end

def menu3
  puts 'menu3'
end

# Let's say we case by selected_menu = :a
selected_menu = :a

# Then just call the relevant method from the hash
send(menu[selected_menu])



11> Lahiru..:

Ruby使用casefor来编写switch语句.

根据Ruby Docs:

case语句由一个可选条件组成,该条件位于参数的位置case,以及零个或多个case子句.when匹配条件的第一个子句(或者,如果条件为null,则评估为布尔真值)"wins",并执行其代码节.case语句的值是success when子句的值,或者when如果没有这样的子句.

案例陈述可以以nil条款结束.每个else语句可以有多个候选值,以逗号分隔.

例:

case x
when 1,2,3
  puts "1, 2, or 3"
when 10
  puts "10"
else
  puts "Some other number"
end

更短的版本:

case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end

正如Honeybadger撰写的这篇博客描述的Ruby Case;

可以与Ranges一起使用:

case 5
when (1..10)
  puts "case statements match inclusion in a range"
end

## => "case statements match inclusion in a range"

可以与Regex一起使用:

case "FOOBAR"
when /BAR$/
  puts "they can match regular expressions!"
end

## => "they can match regular expressions!"

可以与Procs和Lambdas一起使用:

case 40
when -> (n) { n.to_s == "40" }
  puts "lambdas!"
end

## => "lambdas"

此外,可以与您自己的匹配类一起使用:

class Success
  def self.===(item)
    item.status >= 200 && item.status < 300
  end
end

class Empty
  def self.===(item)
    item.response_size == 0
  end
end

case http_response
when Empty
  puts "response was empty"
when Success
  puts "response was a success"
end



12> Sonu Oommen..:

由于switch case始终返回单个对象,我们可以直接打印其结果:

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



13> 123..:

多值时和无值情况:

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


为什么不只是用大小写some_string,当/ \ d /,(填充),当/ [a-zA-Z] /,(填充),结束时(其中,,表示换行)
哦,[此答案](http://stackoverflow.com/a/20441220/1223693)已经覆盖了第一部分,并且许多答案已经提到了正则表达式。坦白说,这个答案没有增加任何新内容,我正在投票删除它。

14> ysk..:

您可以在ruby中以两种不同的方式编写案例表达式.

    类似于一系列"if"语句

    指定案例旁边的目标,并将每个"when"子句与目标进行比较.

第一路

age = 20
case 
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end

第二种方式

case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end



15> 小智..:

你可以用更自然的方式做到这一点,

case expression
when condtion1
   function
when condition2
   function
else
   function
end



16> 小智..:

很多很好的答案,但我想我会添加一个factoid ..如果你试图比较对象(类)确保你有一个太空船方法(不是一个笑话)或理解他们如何被比较

以下是关于该主题的一个很好的讨论 http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/


作为参考,"太空船"方法是"<=>",用于返回-1,0,1或nil,具体取决于比较是返回小于,等于,大于还是不是 - 可比较的.Ruby的[Comparable](http://ruby-doc.org/core-2.0.0/Comparable.html)模块文档解释了它.

17> Prabhakar Un..:
puts "Recommend me a language to learn?"
input = gets.chomp.downcase.to_s

case input
when 'ruby'
    puts "Learn Ruby"
when 'python'
    puts "Learn Python"
when 'java'
    puts "Learn Java"
when 'php'
    puts "Learn PHP"
else
    "Go to Sleep!"
end



18> BrunoFacca..:

如以上许多答案所述,===运算符用于case/ when语句的内幕。

这是有关该运算符的其他信息:

大小写相等运算符: ===

Ruby的许多内置类,例如String,Range和Regexp,提供了它们自己的===运算符实现,也称为“大小写相等”,“三重相等”或“三重相等”。由于在每个类中实现的方式不同,因此根据调用对象的类型,其行为也将有所不同。通常,如果右侧的对象“属于”左侧的对象或属于左侧的对象,则返回true。例如,它可以用来测试一个对象是否是一个类(或其子类之一)的实例。

String === "zen"  # Output: => true
Range === (1..2)   # Output: => true
Array === [1,2,3]   # Output: => true
Integer === 2   # Output: => true

使用其他可能最适合此工作的方法(例如is_a?和)可以达到相同的结果instance_of?

范围执行 ===

===范围对象上调用运算符时,如果右侧的值落在左侧的范围内,则返回true。

(1..4) === 3  # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6  # Output: => false

("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false

请记住,===运算符调用===左侧对象的方法。所以(1..4) === 3等于(1..4).=== 3。换句话说,左侧操作数的类将定义===将调用该方法的哪种实现,因此操作数位置不可互换。

正则表达式的实现 ===

如果右侧的字符串与左侧的正则表达式匹配,则返回true。

/zen/ === "practice zazen today"  # Output: => true
# is similar to
"practice zazen today"=~ /zen/

上面两个示例之间唯一相关的区别是,如果存在匹配项,则===返回true并=~返回一个整数,这是Ruby中的真值。我们将尽快回到这一点。

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有