有没有办法在通用对象上使用 .apply/.unapply?
Is there a way to use .apply/.unapply on Generic objects?
我正在使用通用映射器从 scala 2.11 中的 DBModel 映射模型
它有一个方法定义为:
def fromModelToDBModel(m: T) : R
其中 T 是模型的类型,R 是 DBModel 的类型。
这个方法在几乎所有的继承对象中都是以同样的方式实现的,即:
override def fromModelToDBModel(p: RawModel): RawDBModelV1 = {
val values = RawModel.unapply(p).get
val makeDBModel = (RawDBModelV1.apply _).tupled
makeDBModel(values)
}
是否有可能以某种方式在基本特征中定义一个通用对象,以便我可以对其调用 apply/unapply?
我想实现的逻辑示例:
def fromModelToDBModel(m: T) : R = {
val values = Object[T].unapply(p).get
val makeDBModel = (Object[R].apply _).tupled
makeDBModel(values)
}
这将消除单独编写每个映射器的需要,使代码更干。
您可以使用 Shapeless 研究泛型编程。
使用 Shapeless,您的函数可以写成:
import shapeless._
def fromModelToDBModel[In, Out, Repr <: HList](p: In)(implicit genI: Generic.Aux[In, Repr], genO: Generic.Aux[Out, Repr]): Out = {
val values = genI.to(p)
val makeDBModel = genO.from _
makeDBModel(values)
}
case class RawModel(a: Int, b: String, c: Boolean)
case class RawModelV1(x: Int, y: String, z: Boolean)
val rawModel = RawModel(42, "foo", true)
val rawModelV1 = fromModelToDBModel[RawModel, RawModelV1, Int :: String :: Boolean :: HNil](RawModel(42, "foo", true))
对于所需的显式类型参数,这可能有点笨拙,因此可能需要参考 以了解避免显式类型参数的方法。例如,部分应用:
def fromModelToDBModel2[B] = new PartiallyApplied[B]
class PartiallyApplied[B] {
def apply[A, Repr](a: A)(implicit genA: Generic.Aux[A, Repr], genB: Generic.Aux[B, Repr]) = genB.from(genA.to(a))
}
val rawModelV1_2 = fromModelToDBModel2[RawModelV1](rawModel)
我正在使用通用映射器从 scala 2.11 中的 DBModel 映射模型
它有一个方法定义为:
def fromModelToDBModel(m: T) : R
其中 T 是模型的类型,R 是 DBModel 的类型。
这个方法在几乎所有的继承对象中都是以同样的方式实现的,即:
override def fromModelToDBModel(p: RawModel): RawDBModelV1 = {
val values = RawModel.unapply(p).get
val makeDBModel = (RawDBModelV1.apply _).tupled
makeDBModel(values)
}
是否有可能以某种方式在基本特征中定义一个通用对象,以便我可以对其调用 apply/unapply?
我想实现的逻辑示例:
def fromModelToDBModel(m: T) : R = {
val values = Object[T].unapply(p).get
val makeDBModel = (Object[R].apply _).tupled
makeDBModel(values)
}
这将消除单独编写每个映射器的需要,使代码更干。
您可以使用 Shapeless 研究泛型编程。 使用 Shapeless,您的函数可以写成:
import shapeless._
def fromModelToDBModel[In, Out, Repr <: HList](p: In)(implicit genI: Generic.Aux[In, Repr], genO: Generic.Aux[Out, Repr]): Out = {
val values = genI.to(p)
val makeDBModel = genO.from _
makeDBModel(values)
}
case class RawModel(a: Int, b: String, c: Boolean)
case class RawModelV1(x: Int, y: String, z: Boolean)
val rawModel = RawModel(42, "foo", true)
val rawModelV1 = fromModelToDBModel[RawModel, RawModelV1, Int :: String :: Boolean :: HNil](RawModel(42, "foo", true))
对于所需的显式类型参数,这可能有点笨拙,因此可能需要参考
def fromModelToDBModel2[B] = new PartiallyApplied[B]
class PartiallyApplied[B] {
def apply[A, Repr](a: A)(implicit genA: Generic.Aux[A, Repr], genB: Generic.Aux[B, Repr]) = genB.from(genA.to(a))
}
val rawModelV1_2 = fromModelToDBModel2[RawModelV1](rawModel)