我有一个特征和两个扩展它的案例类:
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类的复制方法。
解决这个问题的正确方法是什么?
答案 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
)