让我说我有
case class Sample(i:Int, b:Boolean)
和
Map[String, String]("i" => "1", "b" => "false")
实例化任何案例类的最简洁方法是什么(如果所有字段都在地图中),签名如下:
get[T](map:[String, String]) : T
可能没有形状可以帮助完成这项任务,但我几乎不熟悉它。谢谢!
答案 0 :(得分:3)
首先,您可以将Map[String, String]
转换为Map[Symbol, Any]
,然后使用类型类shapeless.ops.maps.FromMap
(或扩展方法.toRecord
)和LabelledGeneric
:
import shapeless.LabelledGeneric
import shapeless.record.Record
import shapeless.syntax.std.maps._
case class Sample(i: Int, b: Boolean)
val rec = Map('i -> 1, 'b -> false).toRecord[Record.`'i -> Int, 'b -> Boolean`.T].get
LabelledGeneric[Sample].from(rec) //Sample(1,false)
答案 1 :(得分:1)
如果不使用Shapeless是您的选择,您可以在没有它的情况下以简单的方式完成。下面是一个示例实现,我使用Try Monad和模式匹配将Map转换为您的案例类:
(Try("1".toInt), Try("false".toBoolean)) match {
case (Success(intVal), Success(boolVal)) =>
Sample(intVal, boolVal)
case _ => // Log and ignore the values
}
当然这比Shapeless版本有点冗长,但如果您不想仅仅为这个简单的用例使用完整的库,那么您总是可以使用Scala库来完成它!
答案 2 :(得分:0)
人。可能我不太简洁。我真正需要的是从字符串映射到案例类的通用解析器。感谢您指出LabelledGeneric。这是解决方案:
{literal}
<script>
var dataLayer = window.dataLayer || [];
dataLayer.push({
'event' : 'productData',
'name': 'productName',
'id': 'productId',
'price' : 123
});
</script>
{/literal}