匹配“fallthrough”:为多个案例执行相同的代码?

时间:2010-02-24 12:23:35

标签: scala

Scala编写以下代码的方式是什么:

 int i;

 switch(i) {
   case 1:  
         a();
         break;

   case 2:
   case 15:
        b();
        c();
        break;

   default: foo()        
 } 

即。基于多个案例值执行同一段代码的惯用方法是什么?

 i match {
   case 1  => a    
   case 2  =>
   case 15 => { b
                c }
   case _ => foo        
 } 

看起来似乎不太合适,因为Scala根据第一个匹配的情况评估匹配值,即如果i = 2,代码将不返回任何内容。

感谢您的帮助!

4 个答案:

答案 0 :(得分:51)

根据this conversation,没有任何后果,但您可以使用|

这应该可以解决问题:

i match {
  case 1  => a    
  case 2 | 15 => b
                 c
  case _ => foo        
} 

答案 1 :(得分:10)

Case语句实际上可以包含使用标准if语句的其他逻辑保护。所以你可以这样做:

i match {
  case x if x == 1 => a
  case x if (x == 2 | x == 15) => b; c;
  case _ => foo
}

匹配的保护可以是任何布尔函数或函数组合,因此它比Java中的标准switch语句提供更多的功能。

答案 2 :(得分:3)

虽然这里不适用,但对于更复杂的问题,你可以在某种意义上使用部分函数的andThen函数来“解决”。

 def do_function_a() { println("a"); }
 def do_function_b() { println("b"); }
 val run_function:PartialFunction[String, String] = { 
       case "a" => do_function_a(); "b"
       case "b" => do_function_b(); "c"
 }

 (run_function andThen run_function)("a") // a\nb

答案 3 :(得分:2)

如果您正在处理实际的类(而不是字符串或整数),则在每个类之前需要_:才能将它们加入模式,然后再加入|

sealed trait ShipCondition
case class ShipOnFire() extends ShipCondition
case class FoodSucks() extends ShipCondition
case class MateySnoresTooLoud() extends ShipCondition
case class Ok() extends ShipCondition

val condition = ShipOnFire()

def checkCondition(cond: ShipCondition): Unit = {
  cond match {
    case c @ (_: ShipOnFire | _: FoodSucks) => println("Abandon Ship!") // can also use `c` for something. It has the type ShipCondition
    case (_: MateySnoresTooLoud | _: Ok) => println("Deal with it!")
  }
}

checkCondition(condition) // Abandon Ship!

你也可以进行详尽的检查!请注意,在使用替代模式匹配时,您无法进行案例类解构(例如,case (MateySnoresTooLoud(str) | _: Ok) =>将无法编译。