我正在寻找一种方法,为一个案例类使用两种不同的形式。我试图用额外的构造函数做到这一点,但失败了。请查看代码段:
case class LoginDetails(password: String, field3: Option[Int], field4: String)
case class User(username: String, loginDetails: LoginDetails) {
def this(username: String, password: String, field3: Option[Int], field4: String) = this(username, LoginDetails(password, field3, field4))
// some logic inside
}
val loginDetailsForm = Form(
mapping(
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(LoginDetails.apply)(LoginDetails.unapply))
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(User.apply)(User.unapply))
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))
我要做的是支持两个API(新旧),但是如果我将拥有同一个案例类的两个副本,我将不得不在其他许多地方制作代码逻辑副本的代码。如果有办法做到这一点?
当然,给定的代码不起作用,并且像示例一样使用。
谢谢!
答案 0 :(得分:5)
您可以尝试将方法applyOld
和unapplyOld
添加到协同对象,如下所示:
case class User(username: String, loginDetails: LoginDetails)
object User {
def applyOld(username: String, password: String, field3: Option[Int], field4: String) = new User(username, LoginDetails(password, field3, field4))
def unapplyOld(u: User): Option[(String, String, Option[Int], String)] =
Some((u.username, u.loginDetails.password, u.loginDetails.field3, u.loginDetails.field4))
}
您只需要方法(String, String, Option[Int], String) => User
和User => Option[(String, String, Option[Int], String)]
,您可以将它们放在任何您喜欢的地方。例如,您可以使用方法UserOld
和apply
创建对象unapply
。
用法:
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(User.applyOld)(User.unapplyOld))
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))
答案 1 :(得分:3)
您可以直接在定义表单的位置执行apply / unapply。然后,您不必向case类添加任何新的构造函数。
val oldForm = Form(
mapping(
"username" -> email,
"password" -> text,
"field3" -> optional(number),
"field4" -> text
)(
(username, password, field3, field4) =>
User(username, LoginDetails(password, field3, field4))
)(
(user: User) =>
Option(user.username, user.loginDetails.password, user.loginDetails.field3, user.loginDetails.field4)
)
)
val newForm = Form(
mapping(
"username" -> email,
"loginDetails" -> loginDetailsForm.mapping
)(User.apply)(User.unapply))