gpt4 book ai didi

scala - 在 Scala 中创建现有对象类型的新实例

转载 作者:行者123 更新时间:2023-12-01 09:20:25 25 4
gpt4 key购买 nike

我正在尝试基于某些具体类型的实例创建一个新实例。我有一组类型 {B, C} 是类型 A 的子类型,我需要一些可调用形式的实用程序,它将采用任何现有的 {B, C} 实例并允许创建新实例(允许构造) 基于该类型。

trait A

case class B(name: String) extends A

case class C(name: String) extends A

// I hoped something like this would work, but it doesn't.
def newALike[T <: A](instance: T): T = instance.copy(name = instance.name + "_new")

所需用途:

val b = B("B")
val c = C("C")

val newB = newALike(b)
newB.name // B_new

val newC = newALike(c)
newC.name // C_new

最佳答案

这可行,但可能需要大量重复代码,具体取决于您的应用程序的具体情况:

trait A {
def name: String
}

case class B(override val name: String) extends A

case class C(override val name: String) extends A

trait CanCopy[T] {
def copy(t: T, newName: String): T
}

implicit object canCopyB extends CanCopy[B] {
override def copy(b: B, newName: String) = b.copy(name=newName)
}

implicit object canCopyC extends CanCopy[C] {
override def copy(c: C, newName: String) = c.copy(name=newName)
}

def newALike[T <: A](instance: T)(implicit ev: CanCopy[T]): T =
ev.copy(instance, instance.name + "_new")

问题是 trait A 不知道如何构造后代类的实例的细节。正如 Scala 编译器所看到的,不知道你可以定义什么作为特征 A 的扩展,或者它的构造函数可能采用什么参数。 CanCopy 和隐式对象告诉 Scala 编译器“This 是你构造 B 的方式,而 this 是你构造 C 的方式。”隐式参数的名称是 ev,代表“证据”:它告诉编译器寻找类型 T 可以复制的证据,并且该证据由可以完成工作的对象提供.

根据您的应用程序,您可能可以通过定义另一个特征来避免重复代码,该特征扩展 A,以及 B 和 C 扩展,从而保证具有特定参数的 .copy 方法将可用。然后你可以有一个类型为 CanCopy[ThatIntermediaryTrait] 的隐式对象,它知道调用 .copy 方法。

关于scala - 在 Scala 中创建现有对象类型的新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34081188/

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