如何在Ruby中编写switch语句?


当前回答

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分支

其他回答

你可以用更自然的方式这样做,

case expression
when condtion1
   function
when condition2
   function
else
   function
end

它被称为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替换任意的if/else链(也就是说,即使测试不涉及公共变量),方法是省去初始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在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分支

案例什么时候

为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语句”。

案例当处理类时,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

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