4

我是具有java背景的scala新手。

有没有办法在类继承树中模式匹配超类(或特征),叶子作为案例类和节点抽象类或特征?据我所知,案例类继承是不允许的。

我认为大型继承树中的模式匹配抽象类会非常有帮助

在以下代码中,匹配语句中的最后一种情况在编译期间出错

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字段Employee和方法:unapplyEmployee

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

通过上述更改,处理方法没有问题:

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 回答