如何在Ruby中编写switch语句?
当前回答
多值时和无值情况:
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
其他回答
在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中,procs可以与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语句的工作原理和使用它可以做什么”。)
Ruby在2.7中引入了模式匹配
这是一个超级强大的功能
它也使用case,但有另一种语法
还有查找模式功能
users =
{ users:
[
{ user: 'user', email: 'user@user.com' },
{ user: 'admin', email: 'admin@admin.com' },
]
}
case users
in users: [*, { user:, email: /admin/ => admin_email }, *]
puts admin_email
else
puts "No admin"
end
# will print admin@admin.com
与通常情况不同,如果条件不匹配,将抛出NoMatchingPatternError。所以你可能不得不使用else分支
案例当处理类时,when的行为有点意外。这是因为它使用了==运算符。
该运算符与预期的文字一起工作,但与类不同:
1 === 1 # => true
Fixnum === Fixnum # => false
这意味着如果你想做一个案子。。。当在对象的类上时,这将不起作用:
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
简而言之,可以通过从case obj.class中删除.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
我今天在寻找答案的时候遇到了这个问题,这是第一个出现的页面,所以我认为这对其他处于同样情况的人来说很有用。
如果您渴望知道如何在Ruby开关情况下使用OR条件:
因此,在case语句中,a相当于if语句中的||。
case car
when 'Maruti', 'Hyundai'
# Code here
end
请参阅“Ruby 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,因为||的优先级高于包括
如果您仍然喜欢使用||,即使在这种情况下或更可取,也可以改为使用:(item.include?“A”)||。。。。您可以在这个repl.it中测试它。
推荐文章
- 了解Gemfile。锁文件
- 如何确定一个数组是否包含另一个数组的所有元素
- 是什么导致这个ActiveRecord::ReadOnlyRecord错误?
- 有效,但毫无价值的语法在开关情况下?
- 最好的打印散列的方法
- Rails:dependent =>:destroy VS:dependent =>:delete_all
- 我可以在不包含Ruby模块的情况下调用实例方法吗?
- 如何将新项目添加到哈希
- 测试一个Ruby类是否是另一个类的子类
- 什么时候使用Struct vs. OpenStruct?
- 数组到哈希Ruby
- 我如何让红宝石打印一个完整的回溯而不是截断一个?
- 如何使用RSpec的should_raise与任何类型的异常?
- 如何创建退出消息
- 忽略GEM,因为没有构建它的扩展