scala 匹配“fallthrough”:为多个案例执行同一段代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2325863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:58:01  来源:igfitidea点击:

Match "fallthrough": executing same piece of code for more than one case?

scala

提问by Vlad Gudim

What is the Scala's way to write the following code:

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

 int i;

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

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

   default: foo()        
 } 

I.e. what is the idiomatic way of executing the same piece of code based on multiple case values?

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

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

Doesn't quite seem do the trick, since Scala evaluates the match value based on the first matching case, i.e. if i=2 the code will return nothing.

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

Thanks for help!

感谢帮助!

回答by middus

According to this conversationthere is no fallthrough, but you can make use of |.

根据此对话,没有失败,但您可以使用|.

This should do the trick:

这应该可以解决问题:

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

回答by Aaron

Case statements can actually include additional logic guards using a standard if statement. So you could do something like:

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

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

The matching guards can be any boolean function or composition of functions, so it gives it a lot more power than the standard switch statement in Java.

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

回答by Andy Chase

While not applicable here, for more complex problems you can 'fallthrough' in a sense using the andThen function on partial functions.

虽然在这里不适用,但对于更复杂的问题,您可以在某种意义上使用 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

回答by Jacob Wang

If you are dealing with actual classes (instead of strings or ints), you need _:before each class to make them into a pattern before joining them with |.

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

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!

You get nice exhaustive checking too! Note that you cannot do case class destructuring when using alternative pattern matching (e.g. case (MateySnoresTooLoud(str) | _: Ok) =>will fail to compile.

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