无形大小写 class 转换
shapeless case class conversion
我使用 shapeless 进行 case class 转换,
我有 2 个案例 class:
import shapeless._
case class Foo(id: Int, name: String)
case class Bar(id: Int, name: String, price: Double)
val fooGen = Generic[Foo]
val barGen = Generic[Bar]
val foo = Foo(1, "foo")
val fooRepr = fooGen.to(foo)
val additional = fooRepr :+ 1.0
val bar = barGen.from(additional)
这很好用,但是当我尝试将 Bar 转换为 Foo 时
fooGen.from(barGen.to(bar))
我得到一个错误:
found : main.barGen.Repr
[error] (which expands to) shapeless.::[Int,shapeless.:: [String,shapeless.::[Double,shapeless.HNil]]]
[error] required: main.fooGen.Repr
[error] (which expands to) shapeless.::[Int,shapeless.::[String,shapeless.HNil]]
[error] println(fooGen.from(barGen.to(bar)))
是否可以转换一种情况 class 其中字段比另一种多?
与调整 Foo
的 HList
表示类似,通过添加元素,您还必须调整 Bar
的 HList
表示,通过删除额外的元素:
fooGen.from(barGen.to(bar).take(2))
take
接受一个 Nat
参数,这行代码使用从 Int
文字到 Nat
类型级自然数的隐式转换。
您可以在 shapeless.syntax.hlists.scala
的 HList
上找到其他可用的方法。
我的回答是基于 Travis Brown 之前 提出的一个有点类似的问题。
import shapeless._, ops.hlist._, ops.record._
class SameFieldConverter[T] {
def apply[S, SR <: HList, TR <: HList, MR <: HList, IR <: HList](s: S)(implicit
genS: LabelledGeneric.Aux[S, SR],
genT: LabelledGeneric.Aux[T, TR],
merger: Merger.Aux[SR, HNil, MR],
intersection: Intersection.Aux[MR, TR, IR],
align: Align[IR, TR]) = genT.from(intersection(merger(genS.to(s), HNil)))
}
// defined class SameFieldConverter
def convertTo[T] = new SameFieldConverter[T]
//defined function convertTo
case class Foo(one: String, two: Int, three: Boolean)
// defined class Foo
case class Bar(three: Boolean, one: String)
// defined class Bar
convertTo[Bar](Foo("One", 2, false))
// res26: Bar = Bar(false, "One")
我使用 shapeless 进行 case class 转换, 我有 2 个案例 class:
import shapeless._
case class Foo(id: Int, name: String)
case class Bar(id: Int, name: String, price: Double)
val fooGen = Generic[Foo]
val barGen = Generic[Bar]
val foo = Foo(1, "foo")
val fooRepr = fooGen.to(foo)
val additional = fooRepr :+ 1.0
val bar = barGen.from(additional)
这很好用,但是当我尝试将 Bar 转换为 Foo 时
fooGen.from(barGen.to(bar))
我得到一个错误:
found : main.barGen.Repr
[error] (which expands to) shapeless.::[Int,shapeless.:: [String,shapeless.::[Double,shapeless.HNil]]]
[error] required: main.fooGen.Repr
[error] (which expands to) shapeless.::[Int,shapeless.::[String,shapeless.HNil]]
[error] println(fooGen.from(barGen.to(bar)))
是否可以转换一种情况 class 其中字段比另一种多?
与调整 Foo
的 HList
表示类似,通过添加元素,您还必须调整 Bar
的 HList
表示,通过删除额外的元素:
fooGen.from(barGen.to(bar).take(2))
take
接受一个 Nat
参数,这行代码使用从 Int
文字到 Nat
类型级自然数的隐式转换。
您可以在 shapeless.syntax.hlists.scala
的 HList
上找到其他可用的方法。
我的回答是基于 Travis Brown 之前
import shapeless._, ops.hlist._, ops.record._
class SameFieldConverter[T] {
def apply[S, SR <: HList, TR <: HList, MR <: HList, IR <: HList](s: S)(implicit
genS: LabelledGeneric.Aux[S, SR],
genT: LabelledGeneric.Aux[T, TR],
merger: Merger.Aux[SR, HNil, MR],
intersection: Intersection.Aux[MR, TR, IR],
align: Align[IR, TR]) = genT.from(intersection(merger(genS.to(s), HNil)))
}
// defined class SameFieldConverter
def convertTo[T] = new SameFieldConverter[T]
//defined function convertTo
case class Foo(one: String, two: Int, three: Boolean)
// defined class Foo
case class Bar(three: Boolean, one: String)
// defined class Bar
convertTo[Bar](Foo("One", 2, false))
// res26: Bar = Bar(false, "One")