如何基于另一个类似的案例类创建案例类?

时间:2014-03-31 01:49:37

标签: scala case-class

有两个案例类,它们非常相似:

case class A(aaa:String, bbb:String, ccc:String, ddd:String)

case class B(aaa:String, bbb:String, ccc:String, ddd:String, eee:String)

假设我有一个班级A的实例:

val a = A("111","222","333","444")

有没有办法快速基于B创建类A的实例?

我现在可以这样做(IMO不太好):

val b = B(a.aaa, a.bbb, a.ccc, a.ddd, "some-eee")

1 个答案:

答案 0 :(得分:3)

这对于Shapeless 2.0非常简单(你可以在Shapeless 1.2.4中做到,但会有一些样板):

scala> import shapeless._, syntax.std.product._
import shapeless._
import syntax.std.product._

scala> val b = Generic[B] from a.productElements :+ "some-eee"
b: B = B(111,222,333,444,some-eee)

然后是相反的方向:

scala> val c = Generic[A] from b.productElements.init
c: A = A(111,222,333,444)

这种方法不能确保名称对齐,但是如果你输入错误的类型,它就会抱怨。它也绝对有可能使用这种方法进行更复杂的转换,尽管它可能会有点混乱。例如,假设我们要在参数列表的中间添加一个元素:

case class B(aaa: String, bbb: String, eee: String, ccc: String, ddd: String)

我们需要写下面的内容:

val b = Generic[B].from(
  (a.productElements.take[Nat._2] :+ "some-eee") ++
   a.productElements.drop[Nat._2]
)

仍然没那么可怕。

如果您无法使用像Shapeless这样的东西,那么您当前的解决方案就会好起来。