4

私はJavaのバックグラウンドを持つscalaが初めてです。

ケースクラスとして葉を持ち、ノード抽象クラスまたは特性を持つクラス継承ツリーでスーパークラス(または特性)をパターンマッチする方法はありますか? 私の知る限り、ケース クラスの継承は許可されていません。

大きな継承ツリーの抽象クラスのパターンマッチングは非常に役立つと思います

次のコードでは、コンパイル中の match ステートメント エラーの最後のケース

sealed trait Person {
   def name: String
}

case class Customer(name: String, email: String) extends Person

sealed trait Employee extends Person {
   def id: Int
}

case class Worker(name: String, id: Int, skills: Array[String]) extends Employee

case class Manager(name: String, id: Int, title: String) extends Employee

def process(p: Person) = p match {
   case Customer(_, email) => email
   case Employee(name, _) => name + "@acme.com"
}
4

2 に答える 2

7

nameのフィールドEmployeeunapplyコンパニオン オブジェクトのメソッドがありませんでしたEmployee:

sealed trait Employee extends Person {
  def id: Int
  def name: String
}

object Employee {
  def unapply(e: Employee): Option[(String, Int)] =
    Option(e) map { e =>
      (e.name, e.id)
    }
}

上記の変更により、 process メソッドは問題ありません。

def process(p: Person) = p match {
  case Customer(_, email) => email
  case Employee(name, _) => name + "@acme.com"
}
于 2013-02-11T10:46:07.980 に答える
3

それほど空想的ではありませんが (他の人が構造型で示唆しているように)、非常に実用的だと思います:

def process(p: Person) = p match {
   case Customer(_, email) => email
   case e: Employee => e.name + "@acme.com"
}

特定の既知の値と照合する必要がある場合は、ガードを使用できます。

def process(p: Person) = p match {
   case Customer(_, email) => email
   case e: Employee if e.name == "Joe" => e.name + "@acme.com"
}
于 2013-02-10T20:42:16.720 に答える