加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何使用无形将字段从一个类复制到另一个类

发布时间:2020-12-16 19:23:58 所属栏目:安全 来源:网络整理
导读:是否可以使用无形将1个对象转换为另一个对象 做一些小的转换,比如将Option [T]转换为T. (无需手动定义每个类的映射) 忽略缺少的字段 导入无形._ import shapeless.syntax._ case class Cat(color: Option[Int],isFat: Boolean,newField: String)case class K
是否可以使用无形将1个对象转换为另一个对象

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

导入无形._
import 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))

这失败,出现以下错误
(扩展为)无形的.:[Int,Shapeless.:[Boo,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,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],T2]] =
    new HConv[::[Option[H],T2]] {
      override def convert(list: ::[Option[H],T2] = {
        list.head.getOrElse(default.value) :: conv.convert(list.tail)
      }
    }

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

  implicit def buildHConvString[T <: HList,T2]): HConv[::[String,::[String,T2]] =
    new HConv[::[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)

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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读