15

いくつかのケースクラスで一致させたい。それらがわからない場合は、クラスが拡張する必要がある特定の特性に一致させたいと思います。これは次のようになります

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$

ケースクラスと特性、またはクラスのみでパターンマッチングできないのはなぜですか?

4

2 に答える 2

24

問題は、ケース クラスの特定のインスタンスではなく、コンパニオン オブジェクトを参照していることです。これにより、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 objectsを使用します

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)
}
于 2011-09-29T11:19:37.937 に答える
12

あなたの問題は、括弧のないケースクラスにあります(現在は廃止されています)。ケース クラスは、コンパニオン オブジェクトの作成を意味します。リストとパターン マッチングの両方で結果を括弧なしで記述すると、それはコンパニオン オブジェクトを意味します。

あなたは試すことができます

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

sortOut(Results) // returns companion object
sortout(Results()) // returns instance

これは、2 番目の部分の動作を説明しています。Results はコンパニオン オブジェクトでResults.getClass()あるため、インスタンスのクラスである classOf[Results] ではなく、コンパニオン オブジェクトの (合成) クラスです。Results$

にパラメーターがない場合case class、ほとんどの場合、さまざまなインスタンスを互いに区別できないことを意味し、代わりに を使用する必要がありますcase object。それ以外の場合は、括弧を入れます。

于 2011-09-29T11:17:50.547 に答える