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

scala – 使用Shapeless将Map [String,Any]转换为案例类

发布时间:2020-12-16 09:20:55 所属栏目:安全 来源:网络整理
导读:问题 here询问将案例类映射到Map [String,Any].我想知道将其他方式是什么,将Map [String,Any]转换为案例类.给出以下地图: val mp = Map("name" - "Tom","address" - Map("street" - "Jefferson st","zip" - 10000)) 将其转换为案例类Person: case class Pe
问题 here询问将案例类映射到Map [String,Any].我想知道将其他方式是什么,将Map [String,Any]转换为案例类.给出以下地图:

val mp = Map("name" -> "Tom","address" -> Map("street" -> "Jefferson st","zip" -> 10000))

将其转换为案例类Person:

case class Person(name:String,address:Address)
case class Address(street:String,zip:Int)

val p = Person("Tom",Address("Jefferson st",10000))

有这样的东西:

val newP = mp.asCC[Person]
assert(newP.get == p)

我应该怎么用Shapeless做这个.

解决方法

这是一个袖扣,大多是未经测试的解决方案.首先为类型类:

import shapeless._,labelled.{ FieldType,field }

trait FromMap[L <: HList] {
  def apply(m: Map[String,Any]): Option[L]
}

然后实例:

trait LowPriorityFromMap {
  implicit def hconsFromMap1[K <: Symbol,V,T <: HList](implicit
    witness: Witness.Aux[K],typeable: Typeable[V],fromMapT: Lazy[FromMap[T]]
  ): FromMap[FieldType[K,V] :: T] = new FromMap[FieldType[K,V] :: T] {
    def apply(m: Map[String,Any]): Option[FieldType[K,V] :: T] = for {
      v <- m.get(witness.value.name)
      h <- typeable.cast(v)
      t <- fromMapT.value(m)
    } yield field[K](h) :: t
  }
}

object FromMap extends LowPriorityFromMap {
  implicit val hnilFromMap: FromMap[HNil] = new FromMap[HNil] {
    def apply(m: Map[String,Any]): Option[HNil] = Some(HNil)
  }

  implicit def hconsFromMap0[K <: Symbol,R <: HList,gen: LabelledGeneric.Aux[V,R],fromMapH: FromMap[R],fromMapT: FromMap[T]
  ): FromMap[FieldType[K,V] :: T] = for {
      v <- m.get(witness.value.name)
      r <- Typeable[Map[String,Any]].cast(v)
      h <- fromMapH(r)
      t <- fromMapT(m)
    } yield field[K](gen.from(h)) :: t
  }
}

然后一个帮手班为方便起见:

class ConvertHelper[A] {
  def from[R <: HList](m: Map[String,Any])(implicit
    gen: LabelledGeneric.Aux[A,fromMap: FromMap[R]
  ): Option[A] = fromMap(m).map(gen.from(_))
}

def to[A]: ConvertHelper[A] = new ConvertHelper[A]

和例子:

case class Address(street: String,zip: Int)
case class Person(name: String,address: Address)

val mp = Map(
  "name" -> "Tom","zip" -> 10000)
)

最后:

scala> to[Person].from(mp)
res0: Option[Person] = Some(Person(Tom,Address(Jefferson st,10000)))

这只适用于成员为可成型或成员为可打包类或??其他案例类的其他案例类的案例类(等等).

(编辑:李大同)

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

    推荐文章
      热点阅读