Scala Type Erasure对case类如何解决

时间:2015-09-09 03:52:49

标签: scala implicit

我有一个特征和两个扩展它的案例类:

trait Authenticatable {
  val email: String
  val pass: String
  val id: Long
  val sessionid: String
}

case class Admin(
  id: Long,
  email: String,
  pass: String,
  sessionid: Option[String] = None) extends Authenticatable

case class Client(
  id: Long,
  email: String,
  pass: String,
  sessionid: Option[String] = None) extends Authenticatable

我有函数应该验证用户,使用新的sessionid复制对象并返回它。

  def auth(email: String, password: String): Try[Admin] ={
    checkPass(models.Admin.findBy(sqls"email = $email"), password)
  }

  def auth(email: String, password: String, customer: Customer): Try[Customer] ={
    checkPass(models.Customer.findBy(sqls"email = $email"), password)
  }

  private def checkPass (model: Option[Authenticatable], password: String): Try[Authenticatable]={
    model match {
      case Some(m) => check(password, m.pass).map(_ => m)
      case _ => Failure(new Exception("Authentication failure!"))
    }
  }

问题是:我无法在auth函数中复制对象,因为函数checkPass返回Authenticatable而不是Client或Admin类,而Authenticatable没有case类的复制方法。

解决这个问题的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

如果您使用类型参数,则可以避免丢弃checkPass将始终返回与给定的Authenticable相同类型的private def checkPass[A <: Authenticatable](model: Option[A], password: String): Try[A] = // exactly the same body here 的信息:

auth

这意味着在def auth(email: String, password: String): Try[Admin] = checkPass(models.Admin.findBy(sqls"email = $email"), password) .map(_.copy(sessionid = Some("whatever"))) 中您可以拥有例如:

$option = Array
(
    [name] => test
)