Scala:将通用案例 class 复制到另一个
Scala: Copying a generic case class into another
我有以下设置,我想将 baseData
的实例复制到 moreData
的实例中:
sealed trait baseData {
def weight: Int
def priority: Int
}
sealed trait moreData {
def weight: Int
def priority: Int
def t: String
def id: String
}
case class data1(override val weight: Int, override val priority: Int) extends baseData
case class moreData1 (override val weight:Int, override val priority: Int, override val t: String, override val id: String)extends moreData
所以将myData
复制到下面的otherData
中:
val myData = data1(1,1)
val otherData = moreData1 (2,2,"C","abcd")
会产生:moreData1(1,1,"C","abcd")
.
为此,我想使用具有以下签名的函数,因为我会有不止一种情况 class 扩展 baseData
和 moreData
:
def copyOver[A <:baseData, B <:moreData](from: A, to: B) = {}
我相信您可以使用 Shapeless, but haven't figured out how. There are examples (here) on copying case classes extending a same trait, and others (here) 通过通用表示在不同大小写 class 之间映射值来做到这一点。但是我还没有弄清楚如何将 LabelledGeneric
与传递给 copyOver
的特征边界参数一起使用。我也不想对 otherData
中 myData
中不存在的额外字段进行硬编码。
我正在寻找一个完全通用的实现。有什么想法吗?
您应该可以使用 your first shapeless example 中的 UpdateRepr
类型 class。
您可以使用 UpdateRepr
定义 copyOver
,如下所示:
import shapeless._
// baseData, moreData, data1, moreData1
// UpdateRepr ...
def copyOver[A <: baseData, B <: moreData, R <: HList](
from: A,
to: B
)(implicit
lgen: LabelledGeneric.Aux[A, R],
update: UpdateRepr[B, R]
): B = update(to, lgen.to(from))
您可以按如下方式使用:
val myData = data1(1,1)
val otherData = moreData1(2,2,"C","abcd")
copyOver(myData, otherData)
// moreData1 = moreData1(1,1,C,abcd)
请注意,您可能 运行 遇到 SI-7046 的问题,因为 UpdateRepr
的密封特征(Coproduct)类型 class 派生,您可以在REPL 或拆分 UpdateRepr
和多个文件的密封特征。
我有以下设置,我想将 baseData
的实例复制到 moreData
的实例中:
sealed trait baseData {
def weight: Int
def priority: Int
}
sealed trait moreData {
def weight: Int
def priority: Int
def t: String
def id: String
}
case class data1(override val weight: Int, override val priority: Int) extends baseData
case class moreData1 (override val weight:Int, override val priority: Int, override val t: String, override val id: String)extends moreData
所以将myData
复制到下面的otherData
中:
val myData = data1(1,1)
val otherData = moreData1 (2,2,"C","abcd")
会产生:moreData1(1,1,"C","abcd")
.
为此,我想使用具有以下签名的函数,因为我会有不止一种情况 class 扩展 baseData
和 moreData
:
def copyOver[A <:baseData, B <:moreData](from: A, to: B) = {}
我相信您可以使用 Shapeless, but haven't figured out how. There are examples (here) on copying case classes extending a same trait, and others (here) 通过通用表示在不同大小写 class 之间映射值来做到这一点。但是我还没有弄清楚如何将 LabelledGeneric
与传递给 copyOver
的特征边界参数一起使用。我也不想对 otherData
中 myData
中不存在的额外字段进行硬编码。
我正在寻找一个完全通用的实现。有什么想法吗?
您应该可以使用 your first shapeless example 中的 UpdateRepr
类型 class。
您可以使用 UpdateRepr
定义 copyOver
,如下所示:
import shapeless._
// baseData, moreData, data1, moreData1
// UpdateRepr ...
def copyOver[A <: baseData, B <: moreData, R <: HList](
from: A,
to: B
)(implicit
lgen: LabelledGeneric.Aux[A, R],
update: UpdateRepr[B, R]
): B = update(to, lgen.to(from))
您可以按如下方式使用:
val myData = data1(1,1)
val otherData = moreData1(2,2,"C","abcd")
copyOver(myData, otherData)
// moreData1 = moreData1(1,1,C,abcd)
请注意,您可能 运行 遇到 SI-7046 的问题,因为 UpdateRepr
的密封特征(Coproduct)类型 class 派生,您可以在REPL 或拆分 UpdateRepr
和多个文件的密封特征。