Scala:将地图转换为案例类 [英] Scala: convert map to case class

查看:23
本文介绍了Scala:将地图转换为案例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个示例案例类

Let's say I have this example case class

case class Test(key1: Int, key2: String, key3: String)

我有地图

myMap = Map("k1" -> 1, "k2" -> "val2", "k3" -> "val3")

我需要在代码的几个地方将此映射转换为我的案例类,如下所示:

I need to convert this map to my case class in several places of the code, something like this:

myMap.asInstanceOf[Test]

最简单的方法是什么?我可以以某种方式使用隐式吗?

What would be the easiest way of doing that? Can I somehow use implicit for this?

推荐答案

优雅地执行此操作的两种方法.第一个是使用 unapply,第二个是使用带有类型类的隐式类 (2.10+) 为您进行转换.

Two ways of doing this elegantly. The first is to use an unapply, the second to use an implicit class (2.10+) with a type class to do the conversion for you.

1) unapply 是编写这种转换的最简单、最直接的方法.它没有任何魔法",如果使用 IDE,很容易找到.请注意,执行此类操作可能会使您的伴生对象变得混乱,并导致您的代码在您可能不想要的地方产生依赖关系:

1) The unapply is the simplest and most straight forward way to write such a conversion. It does not do any "magic" and can readily be found if using an IDE. Do note, doing this sort of thing can clutter your companion object and cause your code to sprout dependencies in places you might not want:

object MyClass{
  def unapply(values: Map[String,String]) = try{
    Some(MyClass(values("key").toInteger, values("next").toFloat))
  } catch{
    case NonFatal(ex) => None
  }
}

可以这样使用:

val MyClass(myInstance) = myMap

小心,如果不完全匹配会抛出异常.

be careful, as it would throw an exception if not matched completely.

2) 使用类型类创建隐式类为您创建更多样板,但也允许有很大的空间扩展相同的模式以应用于其他案例类:

2) Doing an implicit class with a type class creates more boilerplate for you but also allows a lot of room to expand the same pattern to apply to other case classes:

implicit class Map2Class(values: Map[String,String]){
  def convert[A](implicit mapper: MapConvert[A]) = mapper conv (values)
}

trait MapConvert[A]{
  def conv(values: Map[String,String]): A
}

举个例子,你会做这样的事情:

and as an example you'd do something like this:

object MyObject{
  implicit val new MapConvert[MyObject]{
    def conv(values: Map[String, String]) = MyObject(values("key").toInt, values("foo").toFloat)
  }
}

然后可以像上面描述的那样使用:

which could then be used just as you had described above:

val myInstance = myMap.convert[MyObject]

如果无法进行转换则抛出异常.使用这种在 Map[String, String] 到任何对象之间转换的模式只需要另一个隐式(并且隐式在范围内.)

throwing an exception if no conversion could be made. Using this pattern converting between a Map[String, String] to any object would require just another implicit (and that implicit to be in scope.)

这篇关于Scala:将地图转换为案例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆