ChatGPT解决这个技术问题 Extra ChatGPT

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

提前致谢!

我认为这是一个 XY 问题;对于所有 doSomething 情况,您都有一个共同的超类,为什么不匹配 case a : MyAbstract 那么...?
抱歉,忘了提,我还有其他类,它们扩展了 MyAbstract 类并且不应该调用 doSomething。
哦,好的,只是想澄清一下:) 不过,您现在对您的问题有了正确的答案。

F
Faiz

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

尝试这个:

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

有没有办法避免括号?因为我有一些参数,它变得丑陋: case a @ (MyFirst(, _, _, _, _) | MySecond(, _, _, _, _)) => doSomething()
你错过了obj @ (_: MyFirst | _: MySecond)吗?
在我在 doSomething 调用中使用它的情况下,我需要 obj。在我的例子中,doSomething 的调用没有使用 obj,所以我不需要它。但无论如何,谢谢你的评论!
@Jean-PhilippePellet 我确实有。让我编辑我的帖子以添加它。
如果编译足够聪明,可以找到最接近的通用类型而不是默认输入类型,那就太好了。