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

如何将地图转换为Scala中的案例类?

发布时间:2020-12-16 09:20:44 所属栏目:安全 来源:网络整理
导读:如果我有一个Map [String,String](“url” – “xxx”,“title” – “yyy”),是否有一种方法来将其转换为case类Image(url:String,标题:字符串)? 我可以写一个帮手: object Image{ def fromMap(params:Map[String,String]) = Image(url=params("url"),ti
如果我有一个Map [String,String](“url” – >“xxx”,“title” – >“yyy”),是否有一种方法来将其转换为case类Image(url:String,标题:字符串)?

我可以写一个帮手:

object Image{
  def fromMap(params:Map[String,String]) = Image(url=params("url"),title=params("title"))
}

但是有没有办法一般地将这一次写入任何案例类的地图?

解决方法

首先,如果您只想缩短代码,则可以使用一些安全的方法.伴侣对象可以被视为一个函数,所以你可以使用这样的东西:

def build2[A,B,C](m: Map[A,B],f: (B,B) => C)(k1: A,k2: A): Option[C] = for {
  v1 <- m.get(k1)
  v2 <- m.get(k2)
} yield f(v1,v2)

build2(m,Image)("url","title")

这将返回一个包含结果的选项.或者,您可以使用Scalaz中的ApplicativeBuilders,内部执行几乎相同但具有更好的语法:

import scalaz._,Scalaz._
(m.get("url") |@| m.get("title"))(Image)

如果真的需要反思,那么最简单的方法就是使用Paranamer(像Lift-Framework一样). Paranamer可以通过检查字节码来恢复参数名称,因此有一个性能命中,并且由于类加载器问题(例如REPL),它不会在所有环境中运行.如果你只使用String构造函数来限制类,那么你可以这样做:

val pn = new CachingParanamer(new BytecodeReadingParanamer)

def fill[T](m: Map[String,String])(implicit mf: ClassManifest[T]) = for {
  ctor <- mf.erasure.getDeclaredConstructors.filter(m => m.getParameterTypes.forall(classOf[String]==)).headOption
  parameters = pn.lookupParameterNames(ctor)
} yield ctor.newInstance(parameters.map(m): _*).asInstanceOf[T]

val img = fill[Image](m)

(请注意,此示例可以选择默认构造函数,因为它不会检查您想要执行的参数计数)

(编辑:李大同)

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

    推荐文章
      热点阅读