gpt4 book ai didi

scala - 如何使用 shapeless 将字段从一个类复制到另一个不同的类

转载 作者:行者123 更新时间:2023-12-01 06:03:17 26 4
gpt4 key购买 nike

是否可以使用 shapeless 将 1 个对象转换为另一个对象

  • 做一些小的转换,比如将 Option[T] 转换为 T
    (无需为每个类手动定义映射)
  • 忽略缺失的字段

  • 进口无形。_
    导入 shapeless.syntax._
    case class Cat(color: Option[Int], isFat: Boolean, newField: String)
    case class Kitten(color: Int, isFat: Boolean)

    val kitten = Kitten(2, true)

    val genCat = Generic[Cat]
    val genKit = Generic[Kitten]

    val cat: Cat = genCat.from(genKit.to(kitten))

    这失败并出现以下错误
    (扩展为)shapeless.::[Int,shapeless.::[Boolean,shapeless.HNil]]

    最佳答案

    这是使用与我的 previous answer 相同的想法的解决方案.

  • 做小的转换(默认值的选项)
  • 忽略尾部字段

  • 当然也有一定的限制。
    object HListsFlatten {

    import shapeless.{::, HList, HNil}

    sealed trait DefaultValue[V] {
    def value: V
    }

    implicit val defaultInt: DefaultValue[Int] = new DefaultValue[Int] {
    override def value = 0
    }

    sealed trait HConv[From <: HList, To <: HList] {
    def convert(list: From): To
    }

    implicit def buildHConvNil: HConv[HNil, HNil] = new HConv[HNil, HNil] {
    override def convert(list: HNil): HNil = HNil
    }

    implicit def buildHConvShorten[H <: AnyVal, T <: HList]
    : HConv[::[H, T], ::[H, HNil]] = new HConv[::[H, T], ::[H, HNil]] {
    override def convert(list: ::[H, T]): ::[H, HNil] = {
    list.head :: HNil
    }
    }

    implicit def buildHConvOption[H, T <: HList, T2 <: HList](
    implicit conv: HConv[T, T2],
    default: DefaultValue[H]): HConv[::[Option[H], T], ::[H, T2]] =
    new HConv[::[Option[H], T], ::[H, T2]] {
    override def convert(list: ::[Option[H], T]): ::[H, T2] = {
    list.head.getOrElse(default.value) :: conv.convert(list.tail)
    }
    }

    implicit def buildHConv[H <: AnyVal, T <: HList, T2 <: HList](
    implicit conv: HConv[T, T2]): HConv[::[H, T], ::[H, T2]] =
    new HConv[::[H, T], ::[H, T2]] {
    override def convert(list: ::[H, T]): ::[H, T2] = {
    list.head :: conv.convert(list.tail)
    }
    }

    implicit def buildHConvString[T <: HList, T2 <: HList](
    implicit conv: HConv[T, T2]): HConv[::[String, T], ::[String, T2]] =
    new HConv[::[String, T], ::[String, T2]] {
    override def convert(list: ::[String, T]): ::[String, T2] = {
    list.head :: conv.convert(list.tail)
    }
    }

    def flatten[A <: HList, B <: HList](list: A)(implicit conv: HConv[A, B]): B =
    conv.convert(list)

    }

    例子:
    import shapeless.Generic

    case class Cat(color: Option[Int], isFat: Boolean, newField: String)
    case class Kitten(color: Int, isFat: Boolean)

    val cat = Cat(color = Some(3), isFat = true, "SomeValue")

    val genCat = Generic[Cat]
    val genKit = Generic[Kitten]

    import HListsFlatten._

    scala> val kitten = genKit.from(flatten(genCat.to(cat)))
    kitten: Kitten = Kitten(3,true)

    关于scala - 如何使用 shapeless 将字段从一个类复制到另一个不同的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42660064/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com