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 === xx === 1..5
when如上所述,这允许使用复杂的条款。可以测试范围,类和各种各样的东西,而不仅仅是相等性。
不像switch其他许多语言的语句,Ruby的case没有落空,所以没有必要结束每when一个break。您还可以在单个when子句中指定多个匹配项,例如when "foo", "bar"。
whenand 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
根据您的情况,您可能更喜欢使用方法的哈希。
如果存在一个很长的whens 列表,并且每个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 expressionx <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...caseC语言的语法:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
这是case...whenRuby中的语法:
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文档。