使用scala中的案例类A的公共前缀成员创建案例类B的实例

时间:2014-10-15 10:45:12

标签: scala

我有一个案例类A,其所有成员变量都与案例类B中的成员变量相同,并且顺序相同。只有B有两个额外的成员变量,它们遵循常见变量。代码如下:

object CaseClassExample {

  case class A(x: Int, y: String, z: Boolean)
  case class B(x: Int, y: String, z: Boolean, a: Option[Int], b: Int)

  def main(args: Array[String]) {
    val a = A(1, "hello", true)
    val b1 = B(expand a members here, None, 2)
    val b2 = B(expand a members here, Some(10), 3)
  }
}

我想使用上面B中的值创建a的实例,并且只提供其他值。像这样:

val b1 = B(expand a members here, None, 2)
val b2 = B(expand a members here, Some(10), 3)

如果不打字太多,我该怎么办? 我可以使用Scala宏吗?

我知道我可以创建辅助构造函数等等。

注意:我的实际班级A有大约18个成员变量。

4 个答案:

答案 0 :(得分:2)

你可以使用无形

来做到这一点
scala> import shapeless.Tuples._
import shapeless.Tuples._

scala> import shapeless.HList._
import shapeless.HList._

scala>  case class A(x: Int, y: String, z: Boolean)
defined class A

scala>   case class B(x: Int, y: String, z: Boolean, a: Option[Int], b: Int)
defined class B

scala>  val a = A(1, "hello", true)
a: A = A(1,hello,true)

scala> val b1 = (B.apply _).tupled((A.unapply(a).get.hlisted ::: (Some(3),5).hlisted).tupled)
b1: B = B(1,hello,true,Some(3),5)

scala> val b1 = (B.apply _).tupled((A.unapply(a).get.hlisted ::: (None,5).hlisted).tupled)
b1: B = B(1,hello,true,None,5)

不知道scala是否内置了这个

答案 1 :(得分:1)

您可以将A作为B

的成员
case class A(x: Int, y: String, z: Boolean)
case class B(anA: A, a: Option[Int], b: Int)
val a = A(1, "hello", true)
val b = B(a, None, 5)

答案 2 :(得分:1)

另一种选择是在案例类B

中编写Apply方法
case class B (x: Int, y: String, z: Boolean, a: Option[Int], b: Int) {
   def apply(aClass: A, newA: Option[Int], newB:Int) {
     B(x = aClass.x,
       y = aClass.y,
       z = aClass.z,
       a = newA,
       b = newB
      )
  }
}

然后你应该能够做到

val aObj = A(3,"name", true)
val bObj = B(aObj, None, 5)

答案 3 :(得分:0)

另一个选择可能是使差分参数可选并合并两种类型:

case class A(x: Int, y: String, z: Boolean, a: Option[Int] = None, b: Option[Int] = None) {
  def toB(newA: Option[Int], newB: Int) = copy(a = newA, b = newB)
  def isB: Boolean = ??? // to test whether it's an A or "B"
}