如何在Ruby中编写switch语句?
答案 0 :(得分:2493)
Ruby使用case
expression代替。
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
没有fall-through,因此无需使用when
结束每个break
。您还可以在单个when
子句中指定多个匹配项,例如when "foo", "bar"
。
答案 1 :(得分:419)
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
我今天在寻找答案时遇到了这个问题,这是第一个出现的页面,所以我认为在同样的情况下对其他人有用。
答案 2 :(得分:199)
由Ruby中的case完成。另请参阅this article on 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
在 The Ruby Programming Lanugage (第1版,O'Reilly)的第123页(我正在使用Kindle)上,它在then
之后显示when
关键字子句可以用换行符或分号替换(就像在if then else
语法中一样)。 (Ruby 1.8也允许使用冒号代替then
......但Ruby 1.9中不再允许使用这种语法。)
答案 3 :(得分:91)
向Chuck's answer添加更多示例:
使用参数:
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警告的the issue。
答案 4 :(得分:69)
许多编程语言,特别是那些源自C的编程语言,都支持所谓的Switch Fallthrough。我正在寻找在Ruby中做同样事情的最佳方法,并认为它可能对其他人有用:
在类C语言中,通常看起来像这样:
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'
执行代码块,但在大多数情况下我发现它类似足以以同样的方式有用。
答案 5 :(得分:66)
在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
您还可以使用带有自定义===
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
(取自“Can procs be used with case statements in 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
(取自“How A Ruby Case Statement Works And What You Can Do With It”的例子。)
答案 6 :(得分:50)
您可以使用正则表达式,例如查找字符串类型:
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示例(不带参数)来完成,只有这种方法对于这些类型的情况更清晰。
答案 7 :(得分:30)
如果您渴望知道如何在Ruby switch案例中使用OR条件:
因此,在case
声明中,,
相当于||
声明中的if
。
case car
when 'Maruti', 'Hyundai'
# Code here
end
答案 8 :(得分:29)
它被称为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
答案 9 :(得分:20)
根据您的情况,您可能更喜欢使用方法哈希。
如果有一个很长的时间列表,并且每个都有一个具体值要与之比较(不是间隔),那么声明方法的散列然后从散列调用相关方法会更有效这一点。
# 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])
答案 10 :(得分:20)
Ruby使用case
来编写switch语句。
根据Ruby Docs:
案例陈述包含一个可选条件,该条件位于 参数的位置为
case
,以及零个或多个when
个子句。 第一个when
子句匹配条件(或评估为 布尔值,如果条件为null)“wins”及其代码节 被执行。 case语句的值是。的值 成功的when
子句,如果没有这样的子句,则为nil
。case语句可以以
else
子句结束。每个when
a 语句可以有多个候选值,用逗号分隔。
示例:
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 and 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
答案 11 :(得分:19)
由于switch case
总是返回单个对象,我们可以直接打印其结果:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
答案 12 :(得分:18)
多值时无值情况:
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
这里有一个regular expression解决方案:
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
答案 13 :(得分:11)
您可以在ruby中以两种不同的方式编写案例表达式。
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
答案 14 :(得分:8)
你可以用更自然的方式做到这一点,
case expression
when condtion1
function
when condition2
function
else
function
end
答案 15 :(得分:8)
很多很棒的答案,但我想我会添加一个factoid ..如果你试图比较对象(Classes),请确保你有一个太空船方法(不是一个笑话)或者理解它们是如何被比较的
以下是对该主题的一个很好的讨论 http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/
答案 16 :(得分:5)
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
答案 17 :(得分:5)
如上面的许多答案中所述,= case运算符在case / when语句的引擎下使用。
以下是有关该运营商的一些额外信息。
许多Ruby的内置类(如String,Range和Regexp)都提供了自己的===运算符实现,也称为case-equality,triple equals或threequals。因为它在每个类中的实现方式不同,所以它的行为会有所不同,具体取决于调用它的对象类型。通常,如果右侧的对象“属于”或“是左侧对象的成员”,则返回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 / ===“今天练习zazen”#输出:=&gt;真正 # 类似于 “今天练习zazen”=〜/ zen /
上面两个例子之间唯一相关的区别是,当匹配时,===返回true而= =返回一个整数,这是Ruby中的真值。我们很快就会回到这里。
答案 18 :(得分:3)
$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
reference =&gt; https://www.tutorialspoint.com/ruby/ruby_if_else.htm
答案 19 :(得分:1)
我已经开始使用:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
在某些情况下,它有助于压缩代码。
答案 20 :(得分:1)
您的环境中是否不支持正则表达式?例如。 Shopify Script Editor(2018年4月):
[错误]:未初始化的常量 RegExp
code = '!ADD-SUPER-BONUS!'
class StrContains
def self.===(item)
item.include? 'SUPER' or item.include? 'MEGA' or\
item.include? 'MINI' or item.include? 'UBER'
end
end
case code.upcase
when '12345PROMO', 'CODE-007', StrContains
puts "Code #{code} is a discount code!"
when '!ADD-BONUS!'
puts 'This is a bonus code!'
else
puts 'Sorry, we can\'t do anything with the code you added...'
end
我在类方法语句中使用了or
,因为||
的优先级高于。{1}}
.include?
。如果您是ruby-nazi,请设想我使用此(item.include? 'A') || ...
代替。 repl.it测试。
答案 21 :(得分:1)
我们可以为多个条件编写switch语句。
例如,
$total='';
答案 22 :(得分:1)
如果您需要“小于”或“大于”:
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
,所以你可以使用你喜欢的。
答案 23 :(得分:0)
在when子句充当||时,强调逗号','是至关重要的。 if语句的含义,即在when子句的分隔表达式之间进行“或”比较而不是“与”比较。因此,请检查以下案例声明。显然,x不小于2,但返回值为'apple'。为什么?因为x为3,并且因为','充当||,所以不必理会表达式'x <2'。
x = 3
case x
when 3, x < 2 then 'apple'
when 3, x > 2 then 'orange'
end
=> "apple"
您可能会认为要执行AND,可以在下面执行以下操作。但这是行不通的。这是因为(3 && x> 2)的计算结果为true,而ruby取True值并将其与===进行比较,这显然是不正确的,因为x为3。
case x
when (3 && x < 2) then 'apple'
when (3 && x > 2) then 'orange'
end
=> nil
要进行&&比较,您必须像对待大小写一样对待,否则阻止:
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
在Ruby编程语言书中,Matz说后一种形式是简单的(并且很少使用)形式,仅是if / elsif / else的替代语法。但是,无论是否经常使用它,对于给定的“何时”子句,我都看不到任何其他方式来附加多个&&表达式。
答案 24 :(得分:0)
case
语句运算符与其他语言中的switch
类似。
这是switch...case
在C语言中的语法:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
这是Ruby中case...when
的语法:
case expression
when constant1, constant2 #Each when statement can have multiple candidate values, separated by commas.
# statements
next # is like continue in other languages
when constant3
# statements
exit # exit is like break in other languages
.
.
.
else
# statements
end
例如:
x = 10
case x
when 1,2,3
puts "1, 2, or 3"
exit
when 10
puts "10" # it will stop here and execute that line
exit # then it'll exit
else
puts "Some other number"
end
有关更多信息,请参见case
文档。
答案 25 :(得分:0)
我更喜欢使用 case + 而非
number = 10
case number
when 1...8 then # ...
when 8...15 then # ...
when 15.. then # ...
end
答案 26 :(得分:0)
Ruby 支持 case 表达式。
类匹配:
case e = StandardError.new("testing")
when Exception then puts "error!"
else puts "ok!"
end # => error!
多值匹配:
case 3
when 1,2,3 then puts "1..3"
when 4,5,6 then puts "4..6"
else puts "?"
end # => 1..3
正则表达式评估:
case "monkey"
when /mon/ then puts "banana"
else puts "?"
end # => banana