成功匹配父类后,是否可以让Scala在类层次结构中保持模式匹配?例如,我期望以下代码打印1和2,但在S
与T
匹配后,Scala将不会继续并匹配下一个案例,因此下一个案例将永远不会可到达的。
class T
class S extends T
new S match {
case _: T => println(1)
case _: S => println(2)
}
答案 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)
}