Scala多类型模式匹配

Scala多类型模式匹配,scala,types,pattern-matching,Scala,Types,Pattern Matching,我想知道如何使用多类型模式匹配。我有: 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

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

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()


提前谢谢

您缺少案例类的括号。 不推荐使用没有参数列表的案例类

试试这个:

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()
}
如果案例类的参数太多,并且不喜欢编写长
Foo(,,…)
模式,那么可能:

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

x match {
   case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB
   case _ => doSomethingElse(x)
}
但也许你只是想要单例对象

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()
}

我认为这是一个XY问题;所有
doSomething
案例都有一个公共超类,为什么不匹配
案例a:MyAbstract
那么…?对不起,忘了提到,我还有其他类,它们扩展了MyAbstract类,不应该调用doSomething。哦,好的,我只是想澄清一下:)你现在对你的问题有了一个正确的答案。可能是重复的,没有办法避免括号?因为我有一些参数,所以它变得很难看:案例a@(MyFirst(,,,,,,,,,,,,,,,,,,,,,,,,,,)MySecond(=>doSomething())你错过了
obj@(
MyFirst;
)了吗?如果我在
doSomething
调用中使用它,我需要
obj
。在我的例子中,
doSomething
的调用没有使用
obj
,所以我不需要它。但无论如何,谢谢你的评论@吉恩·菲利浦:我确实有。让我编辑我的帖子来添加它。如果编译足够聪明,可以找到最接近的公共类型,而不是默认的输入类型,那就太好了。