10

我对 Scala 相当陌生,我有一个关于复制案例类同时保留来自特征的数据的最佳方法的问题。例如,假设我有以下内容:

trait Auditing {

  var createTime: Timestamp = new Timestamp(System.currentTimeMillis)
}

case class User(val userName: String, val email: String) extends Auditing

val user = User("Joe", "joe@blah.com")

然后我想制作一个更改了一个参数的新副本:

val user2 = user.copy(email = "joe@newemail.com")

现在,在上面的示例中,属性 createTime 不会被复制,因为它没有在 User case 类的构造函数中定义。所以我的问题是:假设将 createTime 移动到构造函数中不是一个选项,那么获取包含特征值的 User 对象副本的最佳方法是什么?

我正在使用 Scala 2.9.1

提前致谢!乔

4

3 回答 3

6

您可以使用该行为覆盖复制方法。

case class User(val userName: String, val email: String) extends Auditing
{
  def copy(userName = this.userName, email = this.email) {
   val copiedUser = User(userName, email)
   copiedUser.createTime = createTime
   copiedUser      
  }
}
于 2012-11-02T02:25:02.407 回答
3

虽然除了 Reuben 的解决方案,我没有看到其他解决方案,但我不明白保持构造函数 args 不变的要求。这将是最自然的解决方案:

case class User(userName: String, email: String, 
   override val createTime:Timestamp = new Timestamp(System.currentTimeMillis)) 
      extends Auditing

如果您不希望用户能够覆盖createTime,您仍然可以使用:

case class User private (userName: String, email: String, 
   override val createTime:Timestamp) extends Auditing {
   def this(userName: String, email: String) =
     this(userName, email, new Timestamp(System.currentTimeMillis))
}

唯一的缺点是您需要编写new User("Joe", "joe@blah.com"),因为主构造函数现在是私有的。

于 2012-11-02T07:35:15.043 回答
0

最好不要使用案例类。您可以轻松实现自己需要的功能。下面的代码实现了您想要的复制方法,一个没有 new 的构造函数,隐藏了原始构造函数,并创建了一个提取器,以便您可以在 case 语句中使用 User。

class User private(val userName: String,
                   val email: String,
                   val timeStamp: Timestamp =
                   new Timestamp(System.currentTimeMillis)) {

    def copy(uName: String = userName,
             eMail: String = email) =
    new User(uName, eMail, timeStamp)
}

object User {
  def apply(userName: String, email: String) =
    new User(userName, email)

  def unapply(u: User) = Some((u.userName, u.email, u.timeStamp))
}
于 2017-05-06T05:39:10.327 回答