首页 文章

为什么Scala案例类复制方法仅使用case类中定义的变量进行参数化?

提问于
浏览
0

为什么Scala案例类复制方法仅使用case类中定义的变量进行参数化?

基于问答的问题:

Case class copy does not maintain state of an inherited trait

简短摘要 - 当使用字段定义trait并通过case类扩展时,case类上的 copy 将仅使用case类中定义的变量创建新的类实例,而不使用扩展特征 .

trait A {
    var list: List[Int] = List()

    def add(element: Int) = {
      list = element :: list
    }
  }

  case class B(str: String) extends A {
    val b = B("foo")
    println("B1: " + b.list)

    b.add(1)
    b.add(2)
    b.add(3)
    println("B2: " + b.list)

    val b2 = b.copy(str = "bar")
    println("B3: " + b.list)
    println("B4: " + b2.list)
  }

这里, B4: () 将为空,而 B3:(3,2,1)

2 回答

  • 0

    因为没有合理的方法来做你想要的一贯 .

    对于您的示例, copy 的生成代码可能是

    def copy(str: String = this.str, list: List[Int] = this.list): B = {
      val newB = B(str)
      newB.list = list
      newB
    }
    

    够好了 . 现在如果您将 list 更改为私有,或者 val 而不是 var 会发生什么?在这两种情况下 newB.list = ... 都不会编译,那么编译器应该生成什么代码?

  • 2

    如果你真的想在复制后保留 list 的值(考虑到我在OP的注释中提到的可变性问题),你可以编写自己的 copy 方法 .

    case class B(str: String) extends A {
      def copy(str: String = this.str, list: List[Int] = this.list): B = {
        val newB = B(str)
        list.reverse.foreach(newB.add)
        newB
      }
    }
    

相关问题