Scala 多类型模式匹配

我想知道如何使用多种类型的模式匹配,我有:

abstract class MyAbstract


case class MyFirst extends MyAbstract
case class MySecond extends MyAbstract
case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething()


val x: MyAbstract = MyFirst


x match {
case a: MyFirst => doSomething()
case b: MySecond => doSomething()
case _ => doSomethingElse()
}

所以我想写下这样的话:

x match {
case a @ (MyFirst | MySecond) => doSomething()
case _ => doSomethingElse()
}

我在一些教程中看到了类似的结构,但它给我带来了错误:

pattern type is incompatible with expected type;
[error]  found   : object MyFirst
[error]  required: MyAbstract

那么有没有一种方法来定义几种不同类型的 on case 子句呢?我觉得这样代码会更漂亮。如果我有5个,我将编写5次相同的代码(调用 doSomething ())。

先谢谢你!

70372 次浏览

You are missing the parenthesis for your case classes. Case classes without parameter lists are deprecated.

Try this:

abstract class MyAbstract
case class MyFirst() extends MyAbstract
case class MySecond() extends MyAbstract


val x: MyAbstract = MyFirst()




x match {
case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB)
case _ => doSomethingElse()
}

If you have too many params for your case classes and don't like having to write long Foo(_,_,..) patterns, then maybe:

x match {
case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB)
case _ => doSomethingElse()
}

Or just:

x match {
case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB
case _ => doSomethingElse(x)
}

But perhaps you just wanted singleton case objects?

abstract class MyAbstract
case object MyFirst extends MyAbstract
case object MySecond extends MyAbstract


val x: MyAbstract = MyFirst


x match {
case aOrB @ (MyFirst | MySecond) => doSomething()
case _ => doSomethingElse()
}