Answers:
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"
。
when
and return
语句放在同一行when "foo" then "bar"
then
。另请参阅其他答案。
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
我今天在寻找答案时遇到了这个问题,这是第一个出现的页面,因此我认为它对处于相同情况的其他人很有用。
.class
部分有趣的是,谢谢。当然,这是完全适当的行为(尽管我可以看到认为可以打印的常见错误It is a string
)……您正在测试某个任意对象的类,而不是对象本身。因此,举例来说:case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
在结果:"Class!"
该方法适用于相同的1.class
,{}.class
等滴药.class
,我们得到"String!"
或者"Something else"
这些不同的值。
这是case
在Ruby中使用完成的。另请参阅Wikipedia上的“ 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编程语言(第1版,O'Reilly)》的第123页左右,它说then
该when
子句后面的关键字可以用换行符或分号代替(就像if then else
语法中一样)。(Ruby 1.8还允许使用冒号代替then
,但Ruby 1.9中不再允许使用此语法。)
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
我不必说每行,而只需复制您所做的事情。更优雅,我也更喜欢
在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警告的“ 如何在Ruby中编写switch语句 ”。
or
许多编程语言(尤其是从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'
or 之前不可能执行代码块'c'
,但是在大多数情况下,我发现它足够相似,可以用相同的方式使用。
在Ruby 2.0中,您还可以在case
语句中使用lambda ,如下所示:
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
(示例摘自“ procs是否可以与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 Case语句如何工作以及您可以如何使用它 ”。)
您可以使用正则表达式,例如查找字符串类型:
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示例(不带参数)完成此操作,只有这种方法对于此类情况更干净。
如果您想知道如何在Ruby转换案例中使用OR条件:
因此,在一条case
语句中,a ,
等同||
于一条if
语句。
case car
when 'Maruti', 'Hyundai'
# Code here
end
请参阅“ Ruby Case语句如何工作以及如何使用它 ”。
这就是所谓的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
Ruby使用case
编写开关语句。
根据case
文档:
Case语句包含一个可选条件,该条件位于和的参数的位置
case
以及零个或多个when
子句。when
匹配条件的第一个子句(或如果条件为null则求值为布尔真)“获胜”,并执行其代码节。case语句的值是成功when
子句的值,或者nil
如果没有这样的子句的话。case语句可以以
else
子句结尾。每个when
语句可以有多个候选值,以逗号分隔。
例:
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
正如“ Ruby的案例陈述-高级技术 ”所描述的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
根据您的情况,您可能更喜欢使用方法的哈希。
如果存在一个很长的when
s 列表,并且每个s具有要比较的具体值(而不是一个间隔),则声明方法的哈希,然后像这样从哈希中调用相关的方法将更为有效。
# 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])
由于switch case
始终返回单个对象,因此我们可以直接打印其结果:
puts case a
when 0
"It's zero"
when 1
"It's one"
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 some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(在哪里,
意味着换行)
您可以case
在Ruby中以两种不同的方式编写表达式:
if
陈述case
每个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
很多不错的答案,但我想我会添加一个模拟对象。
“ Ruby平等和对象比较 ”是对该主题的一个很好的讨论。
<=>
,用于根据比较结果分别返回小于,等于,大于还是不可比较,返回-1、0、1或nil。Ruby的Comparable模块文档对此进行了解释。
如以上许多答案所述,===
运算符用于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中的真值。我们将尽快回到这一点。
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
$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,除非 ”。
您的环境中不支持正则表达式?例如Shopify脚本编辑器(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
在类方法语句中使用s,因为||
它的优先级高于
.include?
。如果您是红宝石纳粹分子,请想象我用了它(item.include? 'A') || ...
。repl.it测试。
,
在when
子句中强调逗号()非常重要。它充当||
一个的if
说法,那就是它的OR比较,而不是与该的分隔符的表达式之间的比较when
条款。请参阅以下案例声明:
x = 3
case x
when 3, x < 2 then 'apple'
when 3, x > 2 then 'orange'
end
=> "apple"
x
不小于2,但返回值为"apple"
。为什么?因为x
是3,并且因为',`` acts as an
|| , it did not bother to evaluate the expression
x <2'。
您可能会认为要执行AND,您可以在下面执行以下操作,但这不起作用:
case x
when (3 && x < 2) then 'apple'
when (3 && x > 2) then 'orange'
end
=> nil
它不工作,因为(3 && x > 2)
计算结果为真实的,和Ruby取真值,并将其与x
同===
,这是不正确的,因为x
是3。
做一个&&
比较,你将不得不对待case
像if
/ else
块:
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
在Ruby编程语言的书,马茨说,这后一种形式是简单的(和不经常使用)的形式,这无非是一个替代语法if
/ elsif
/ else
。但是,无论是否经常使用它,我都看不到任何其他方式可以&&
为给定when
子句附加多个表达式。
if...elsif
?似乎您正在尝试混合一个case语句和一个条件。为什么?只需将条件放在 when块中,例如。when 3; ( x < 2 ) ? 'apple' : 'orange'
我们可以为多个条件编写switch语句。
例如,
x = 22
CASE x
WHEN 0..14 THEN puts "#{x} is less than 15"
WHEN 15 THEN puts "#{x} equals 15"
WHEN 15 THEN puts "#{x} equals 15"
WHEN 15..20 THEN puts "#{x} is greater than 15"
ELSE puts "Not in the range, value #{x} "
END
case
,when
,end
)是区分大小写的,并且不能是大写这样。
NoMethodError (undefined method
CASE'for main:Object)`。正如@ sondra.kinsey所说,您不能使用大写。Ruby会认为它是恒定的。
该case
声明运营商像switch
其他语言。
这是switch...case
C语言的语法:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
这是case...when
Ruby中的语法:
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
文档。