Scala模式匹配类层次结构

时间:2016-03-26 06:10:15

标签: scala pattern-matching

成功匹配父类后,是否可以让Scala在类层次结构中保持模式匹配?例如,我期望以下代码打印1和2,但在ST匹配后,Scala将不会继续并匹配下一个案例,因此下一个案例将永远不会可到达的。

class T
class S extends T

new S match {
  case _: T => println(1)
  case _: S => println(2)
}

4 个答案:

答案 0 :(得分:3)

始终选择第一个匹配的大小写。在测试父类T之前,只需交换订单并测试子类型S.或者您可以使用嵌套模式匹配。

答案 1 :(得分:1)

我能想到的最接近的就是这样,

class T
class S extends T

new S match {
 case c@ (_: T  | _: S ) => println(1)
}

通过这种方式,您可以检查new S是否属于其中任何一种类型。

答案 2 :(得分:1)

Scala模式匹配不支持堕落。我刚才问过这个确切的问题(Scala pattern matching - match multiple successful cases

您需要针对每种可能的情况单独进行。

如果你的实际用例不同(即你有几十个这样的条件而你需要以优雅的方式顺序执行它们) - 我可能会选择使用不同的方法而不是模式匹配。

可能,我会做的(维护功能范例)将是这样的:

class T
class S extends T

val myTestedVal = new S

((x:T) => ( 
    (x match { case z:S => (()=>println(2)) case _ => } ) ::
    (x match { case z:T => (()=>println(1)) case _ => } ) ::
    // Add other cases here
     Nil)) (myTestedVal).collect { case i:(()=>Unit) => i }.foreach(z => z())

以上示例代码将为S打印2和1,为T打印1。它的作用是,它基本上运行条件列表,根据成功条件创建要运行的函数列表,然后在foreach中执行它们(也可以修改为map如果你需要函数来返回有意义的值)。

注意

对于OP的简单用例,上述方法肯定是过度的。但是,如果您希望以“规则引擎”样式执行多个条件,则上述方法比具有长链“if”语句更加优雅和“实用”。

免责声明:我自己对Scala和FP有点新鲜。

答案 3 :(得分:1)

将模式匹配视为if-else if - else -if ...语句的序列。您不能执行多个分支。根据选择器的复杂程度,它的方法是嵌套:

new S match {
   case t: T => println(1)
       t match {
         case _: S => println(2)
       }
}

或复制多个分支中的一些操作:

new S match {
   case _: S => println(2); println(1)
   case _: T => println(1)
}

或者使用部分功能,这可能对你的情况有些过分,但仅仅是为了完整性:

Option(new S).map { 
  case s:S => println(2); s
  case s => s
}.collect { 
  case _:T => println(1) 
}