如何用Ruby编写Switch语句

jxct1oxe  于 2022-09-21  发布在  Ruby
关注(0)|答案(6)|浏览(175)

如何用Ruby编写switch语句?

w8f9ii69

w8f9ii691#

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没有落差,因此没有必要以break结束每个when。您还可以在单个when子句中指定多个匹配项,如when "foo", "bar"

eulz3vhy

eulz3vhy2#

在处理类时,case...when的行为有点出乎意料。这是因为它使用了===运算符。

该运算符与预期的文字一起使用,但不与类一起使用:

这意味着,如果要对对象的类执行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

简而言之,可以通过从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

我今天在寻找答案的时候遇到了这个问题,这是第一个出现的页面,所以我想它对其他和我有同样情况的人也很有用。

n3h0vuf2

n3h0vuf23#

这是在Ruby中使用case完成的。另请参阅维基百科上的“切换声明”。

引述:

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编程语言(第一版,O‘Reilly)的第123页上,它说when子句后面的then关键字可以用换行符或分号代替(就像在if then else语法中一样)。(Ruby 1.8还允许用冒号代替then,但在Ruby 1.9中不再允许这种语法。)

vbopmzt1

vbopmzt14#

案例...当

要向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警告的“如何用Ruby编写Switch语句”。

ax6ht2ek

ax6ht2ek5#

在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

(摘自“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”。)

s8vozzvw

s8vozzvw6#

许多编程语言,特别是那些从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',但在大多数情况下,我发现它们足够相似,可以用相同的方式使用。

相关问题