首页 文章

Scala:使用特征复制案例类

提问于
浏览
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

提前致谢!乔

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      
      }
    }
    
  • 0

    虽然我没有看到任何其他解决方案而不是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") ,因为主要构造函数现在是私有的 .

  • 3

    你最好不要使用案例类 . 您可以轻松实现自己需要的功能 . 下面的代码实现了你想要的copy方法,没有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))
    }
    

相关问题