您可以通过在案例类中声明列表来完成此操作,并通过声明方法来满足您的特征类型。所以:
trait A {
def list: List[Int]
}
case class B(i: Int, var list: List[Int]) extends A
然后是你的例子:
scala> val b = B(2, List(1))
b: B = B(2,List(1))
scala> b.list = List(3)
b.list: List[Int] = List(3)
scala> println("B: " + b.list)
B: List(3)
scala> println("Copied: " + b.copy(i = 4).list)
Copied: List(3)
我不知道您在做什么需要在您的班级中使用可变列表,但我想即使这满足您的示例,它也可能无法满足您正在处理的任何问题,因为:
scala> val a: A = b
a: A = B(2,List(3))
scala> a.list
res2: List[Int] = List(3)
scala> a.list = List(4)
<console>:15: error: value list_= is not a member of A
a.list = List(4)
当尝试将B 的实例作为A 查看时,您将无法分配列表类型。如果您正在处理 A 的实例,则必须执行类似的操作
scala> a match {
| case itsAB: B => itsAB.list = List(4); itsAB
| case other => other
| }
res3: A = B(2,List(4))
但无论哪种方式,这都是你要做的。要么这样,要么您可以按照 phongnt 的建议创建一个非案例类并自己定义一个复制方法。
在你说的评论中:
我没有提到 trait 属性需要通过引用 trait 本身来修改
但这对我来说听起来像是全局可变状态。如果你真的需要,我鼓励你不要这样做然后你可以使用一个对象:
object A {
@volatile
var list = List.empty[Int]
}
但是我怀疑这是否符合您在问题中所表达的意思,因为这里每个实例都没有单独的列表。所以......看看你更新的问题,我只能猜测你想要完成的事情是这样的:
object A {
@volatile
var list = List.empty[Int]
}
trait A {
def list = A.list
def add(i: Int) = A.list = i :: A.list
}
case class B(str: String) extends A
这让你:
scala> val b = B("hi")
b: B = B(hi)
scala> b.add(0)
scala> b.add(1)
scala> A.list
res4: List[Int] = List(1, 0)
但同样,这是全局可变状态,这不是一件好事。它不是线程安全的。因此,如果有办法让您在不这样做的情况下找出问题...我鼓励您这样做。