gpt4 book ai didi

scala - 案例类副本不维护继承特征的状态

转载 作者:行者123 更新时间:2023-12-04 16:41:16 25 4
gpt4 key购买 nike

假设我定义了一个特征和扩展它的案例类:

    trait A {
var list: List[Int] = List()
def add(i: Int) = list = i :: list
}

case class B(str: String) extends A

如果我随后创建 B 的实例,修改列表并制作它的副本,副本将采用特征 A 中定义的列表值:

    val b = B("foo")
b.add(3)
println("B: " + b.list)
println("Copied: " + b.copy(str = "bar").list)

输出:

B: List(3)

Copied: List()

我知道这可能不是很好的函数式编程实践,但是有没有办法强制 B 的副本采用列表的更改版本,例如 b?

最佳答案

您可以通过在案例类中声明列表来实现这一点,并通过声明一个方法来满足您的特征类型。所以:

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)

我不知道你在做什么需要在你的类(class)中有一个可变列表,但我想即使这满足了你的例子,但它可能无法满足你正在处理的任何问题,因为:

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 的建议创建一个非案例类并自己定义一个复制方法。

在评论中你说:

I failed to mention that the trait attribute needs to be modifiable with a reference to the trait itself

但这对我来说听起来像是全局可变状态。如果你真的需要它,我鼓励你不要那么你可以使用一个对象:

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)

但同样,这是全局可变状态,这不是一件好事。它不是线程安全的。因此,如果有一种方法可以让您在不执行此操作的情况下找出问题...我鼓励您这样做。

关于scala - 案例类副本不维护继承特征的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48812293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com