【问题标题】:shapeless case class conversion无形案例类转换
【发布时间】:2016-03-17 20:57:30
【问题描述】:

我使用 shapeless 进行案例类转换, 我有一个 2 案例类:

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)))    

是否可以转换一个字段比另一个字段多的案例类?

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:

    与调整FooHList 表示类似,通过添加一个元素,您还必须通过删除额外元素来调整BarHList 表示:

    fooGen.from(barGen.to(bar).take(2))
    

    take 接受Nat 参数,这行代码使用从Int 文字到Nat 类型级自然数的隐式转换。

    您可以在HLists 的shapeless.syntax.hlists.scala 中找到其他可用的方法。

    【讨论】:

      【解决方案2】:

      我的回答是基于 Travis Brown 之前的 answer 提出的一个有点类似的问题。

      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")
      

      【讨论】:

      猜你喜欢
      • 2020-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 2014-12-18
      • 1970-01-01
      相关资源
      最近更新 更多