使用 shapeless scala 合并两个不同 case 的字段 类

Using shapeless scala to merge the fields of two different case classes

我想将两个不同案例 class 的字段合并为一个案例 class。

例如,如果我有以下情况classes:

case class Test(name:String, questions:List[Question], date:DateTime)

case class Answer(answers:List[Answers])

我想要一种简洁的无形方式将两者合并为:

TestWithAnswers(name:String, questions:List[Question], date:DateTime, answers:List[Answer]). 

那里有一个很好的无形答案吗?

你可以使用 shapeless Generic 来做到这一点。

val t: Test = ???
val a: Answer = ???
val gt = Generic[Test]
val ga = Generic[Answer]
val gta = Generic[TestWithAnswers]

val ta = gta.from(gt.to(t) ++ ga.to(a))

或者,如果你喜欢单行本

val ta = Generic[TestWithAnswers].from(Generic[Test].to(t) ++ Generic[Answer].to(a))

假设 tTest 的一个实例并且 aAnswer 的一个实例,ta 将是 [=19= 的一个实例].

快速解释:Generic 可以将大小写 class 与通用 HList 表示相互转换。因此,鉴于您的 classes 的结构,您可以简单地将测试和答案都转换为一个 hlist,将两个列表连接成一个列表并从中构建一个 TestWithAnswers 实例。

这是一个更简单的示例,您可以复制粘贴并在 REPL 中尝试

import shapeless._
case class A(a: Int)
case class B(a: String)
case class AB(a: Int, b: String)
Generic[AB].from(Generic[A].to(A(42)) ++ Generic[B].to(B("foo")))
// AB(42, "foo")