Scala多种类型模式匹配


79

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

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

提前致谢!


我认为这是一个XY问题;您在所有doSomething情况下都有一个共同的超类,为什么不匹配case a : MyAbstract那么...?
PatrykĆwiek2013年

对不起,忘了提一下,我还有其他类,这些类扩展了MyAbstract类,因此不应调用doSomething。
psisoyev

哦,好吧,只是想澄清一下:)尽管您现在对问题有正确的答案。
PatrykĆwiek2013年

Answers:


133

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

试试这个:

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

1
还有没有办法避免括号?由于我有一些参数,而且变得很丑陋:case a @(MyFirst(,_,_,_,_ | | MySecond(,_,_,_,_))=> doSomething()
psisoyev 2013年

9
你想念obj @ (_: MyFirst | _: MySecond)吗?
Jean-Philippe Pellet

我需要objdoSomething呼叫中使用它的情况下。就我而言,的调用doSomething未使用obj,因此我不需要它。但是无论如何,谢谢您的评论!
psisoyev

@ Jean-PhilippePellet确实我有。让我编辑我的帖子以添加它。
Faiz

1
如果编译足够智能以找到最接近的通用类型而不是默认使用输入类型,那就太好了。
nilskp 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.