Scala: смешивать черты и классы дел в сопоставлении с образцом - PullRequest
14 голосов
/ 29 сентября 2011

Я хочу сопоставить некоторые классы дел.Если я их не знаю, я хочу найти соответствие по определенной характеристике, которую должны расширять классы.Это выглядит как

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$

Почему я не могу сопоставить шаблон с регистромкласс и черты характера или только на класс?

спасибо заранее, Муки

Ответы [ 2 ]

24 голосов
/ 29 сентября 2011

Проблема в том, что вы ссылаетесь на сопутствующие объекты для ваших классов дел, а не на их конкретные экземпляры. В связи с этим 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

и

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

или, как предлагает Дидье, использовать case object 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

и

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)
}
12 голосов
/ 29 сентября 2011

Ваша проблема с классом дел без паратезов (которые сейчас устарели).Класс 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$

Если case class имеетбез параметров, в большинстве случаев это означает, что различные экземпляры нельзя отличить друг от друга, и вам лучше использовать case object.В противном случае поставьте паратезы.

...