如何在Ruby中编写switch
语句?
#1楼
案例...当
在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语句 ”。
#2楼
您可以使用正则表达式,例如查找字符串类型:
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示例(不带参数)完成此操作,只有这种方法对于此类情况更干净。
#3楼
在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语句如何工作以及您可以如何使用它 ”。)
#4楼
很多很好的答案,但我想我会添加一个事实。.如果您尝试比较对象(类),请确保您具有太空飞船方法(不是开玩笑)或了解如何比较它们
“ Ruby的平等和对象比较 ”是对该主题的一个很好的讨论。
#5楼
由于switch case
始终返回单个对象,因此我们可以直接打印其结果:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
#6楼
许多编程语言(尤其是从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'
之前执行一段代码,但是在大多数情况下,我发现它足够相似,可以用相同的方式使用。
#7楼
多值时间和无值情况:
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
#8楼
如果您想知道如何在Ruby转换案例中使用OR条件:
所以,在一个case
声明,一,
是相当于||
在if
语句中。
case car
when 'Maruti', 'Hyundai'
# Code here
end
请参阅“ Ruby Case语句如何工作以及如何使用它 ”。
#9楼
我已经开始使用:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
在某些情况下,它有助于压缩代码。
#10楼
根据您的情况,您可能更喜欢使用方法的哈希。
如果有一个长的列表when
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])
#11楼
这就是所谓的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
#12楼
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
#13楼
您可以更自然地做到这一点,
case expression
when condtion1
function
when condition2
function
else
function
end
#14楼
如以上许多答案所述,在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?
可以达到相同的结果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中的真实值。 我们将尽快回到这一点。
#15楼
Ruby使用这种case
来编写switch语句。
根据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
#16楼
您可以在Ruby中以两种不同的方式编写case
表达式:
- 类似于一系列的
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
#17楼
$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,除非 ”。
#18楼
您的环境中不支持正则表达式? 例如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?
更高的优先级.include?
。 如果您是红宝石 (item.include? 'A') || ...
,请想象我使用了这个(item.include? 'A') || ...
(item.include? 'A') || ...
代替。 repl.it测试。
#19楼
我们可以为多个条件编写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
#20楼
在when
子句中强调逗号( ,
)是至关重要的。 它充当||
if
语句的意思是,它在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)
计算结果为true,而Ruby获取True值,并使用===
将其与x
进行比较,这是不正确的,因为x
为3。
要进行&&
比较,您必须将case
视为if
/ else
块:
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
Matz在Ruby Programming Language一书中说,后一种形式是简单的(且不经常使用)形式,无非是if
/ elsif
/ else
的替代语法。 但是,无论是否经常使用它,对于给定的when
子句,我看不到任何其他方式附加多个&&
表达式。
#21楼
case...when
处理类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
我今天在寻找答案时遇到了这个问题,这是第一个出现的页面,因此我认为它对处于相同情况的其他人很有用。
#22楼
case
语句运算符就像其他语言中的switch
一样。
这是C语言中switch...case
的语法:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
这是case...when
的语法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
文档。
#23楼
这是通过在Ruby中使用case
来完成的。 另请参阅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页左右,它说了when
子句后面的then
关键字可以用换行符或分号代替(就像if then else
语法一样)。 (Ruby 1.8还允许使用冒号代替then
,但是Ruby 1.9中不再允许使用此语法。)
#24楼
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"
。