Scala:模式匹配中的混合特征和案例类

Scala:模式匹配中的混合特征和案例类,scala,pattern-matching,traits,case-class,Scala,Pattern Matching,Traits,Case Class,我想匹配一些案例类。如果我不知道它们,我想匹配类必须扩展的特定特性。这看起来像 trait Event //root trait trait Status extends Event //special trait trait UIEvent extends Event //special trait case class Results extends Event //concrete case class case class Query extends Event //c

我想匹配一些案例类。如果我不知道它们,我想匹配类必须扩展的特定特性。这看起来像

trait Event  //root trait
trait Status extends Event  //special trait
trait UIEvent extends Event //special trait

case class Results extends Event   //concrete case class
case class Query extends Event     //concrete case class

case class Running extends Status  //concrete case class
case class Finished extends Status //concrete case class

case class Update extends UIEvent  //concrete case class
我运行以下测试

  val events = List(Results, Query, Running, Finished, Update)
    events foreach {
      case Results => println("Got a Results")
      case Running => println("Got a Running")
      case s:Status => println("Got some StatusEvent")
      case ui:UIEvent => println("Got some UIEvent")
      case e: Event => println("Generic Event")
      case x => println("Didn't matched at all " + x)
    }
    println("############################")
    val STATUS = classOf[Status]
    val EVENT = classOf[Event]
    val UIEVENT = classOf[UIEvent]
    val RESULTS = classOf[Results]
    val eventsClass = events map (_.getClass)
    eventsClass foreach {
      case RESULTS => println("Got a Results")
      case STATUS => println("Got some StatusEvent")
      case UIEVENT =>  println("Got some UIEvent")
      case EVENT => println("Generic Event")
      case x => println("Didn't matched at all " + x)
    }
这将导致以下输出

Got a Results
Didn't match at all Query
Got a Running
Didn't match at all Finished
Didn't match at all Update
############################
Didn't match at all class de.mukis.scala.test.main.Results$
Didn't match at all class de.mukis.scala.test.main.Query$
Didn't match at all class de.mukis.scala.test.main.Running$
Didn't match at all class de.mukis.scala.test.main.Finished$
Didn't match at all class de.mukis.scala.test.main.Update$

为什么我不能在case类和traits上进行模式匹配,或者仅仅在类上进行模式匹配?

您的问题在于case类没有妄想症(现在不推荐使用)。case类意味着创建一个伴随对象。当您在列表中和模式匹配中写入结果而没有偏执时,它意味着伴随对象

你可以试试

define sortOut(x: Any) = x match {
  case Results => "companion object"
  case Results() => "instance"
}

sortOut(Results) // returns companion object
sortout(Results()) // returns instance
这解释了第二部分中的行为。由于Results是伴随对象,
Results.getClass()
不是classOf[Results],它是实例类,而是伴随对象的(合成)类,
Results$


如果
案例类
没有参数,大多数情况下这意味着各种实例无法相互区分,您应该使用
案例对象
。否则,就把这些偏执放在这里。

问题在于,您引用的是案例类的伴随对象,而不是它们的特定实例。由于此原因,REPL应该已经向您提供了弃用警告

解决方案是添加几个括号:

sealed abstract trait Event
sealed abstract trait Status extends Event
sealed abstract trait UIEvent extends Event

case class Results() extends Event
case class Query() extends Event

case class Running() extends Status
case class Finished() extends Status

case class Update() extends UIEvent

或者,正如迪迪尔德所建议的,使用
case对象
s

sealed abstract trait Event
sealed abstract trait Status extends Event
sealed abstract trait UIEvent extends Event

case object Results extends Event
case object Query extends Event

case object Running extends Status
case object Finished extends Status

case object Update extends UIEvent


谢谢你的快速回答。我在哪里可以找到这些更改,哪种代码样式不推荐,哪种不推荐(我很幸运地在某个地方读到case类继承不推荐)。在repl中检查sortOut之前,我不知道它不推荐,只知道它很危险。我在changse的列表中找不到它(邮件列表和StackOverflow上的一些参考资料)。但是请注意,这不是语言更改,只是添加了一个警告(暗示将来可能不再支持它),但在弃用之前,行为是相同的。per,
trait
中的
abstract
是多余的。既然它是多余的,那么我想它是无害的。但是,你把它包括在这里有什么特别的原因吗,@Kevin?
sealed abstract trait Event
sealed abstract trait Status extends Event
sealed abstract trait UIEvent extends Event

case object Results extends Event
case object Query extends Event

case object Running extends Status
case object Finished extends Status

case object Update extends UIEvent
val events = List(Results, Query, Running, Finished, Update)
events foreach {
  case Results => println("Got a Results")
  case Running => println("Got a Running")
  case s:Status => println("Got some StatusEvent")
  case ui:UIEvent => println("Got some UIEvent")
  case e: Event => println("Generic Event")
  case x => println("Didn't match at all " + x)
}