Scala案例类映射扩展

时间:2012-01-05 18:12:21

标签: scala object dynamic map expansion

在groovy中可以做到:

class Foo {
  Integer a,b
}
Map map = [a:1,b:2]
def foo = new Foo(map) // map expanded, object created

据我所知,Scala对Groovy这个词没有任何意义,但我想知道在这种情况下是否支持地图扩展

简单地说,我尝试过但失败了:

case class Foo(a:Int, b:Int)
val map = Map("a"-> 1, "b"-> 2)
Foo(map: _*) // no dice, always applied to first property

相关thread,显示问题的可能解决方案。

现在,从我能够挖掘的内容来看,至少从Scala 2.9.1开始,关于案例类的反思基本上是无操作的。然后,净效应似乎是被迫进入某种形式的手动对象创建,考虑到Scala的强大功能,这有点具有讽刺意味。

我应该提一下,用例涉及servlet请求参数映射。具体来说,使用Lift,Play,Spray,Scalatra等,我想采用已清理的params映射(通过路由层过滤)并将其绑定到目标案例类实例,而无需手动创建对象,也不指定其类型。这需要“可靠”的反射,并且需要像“str2Date”那样来处理类型转换错误。

也许在2.10中使用新的反射库,实现上面的将是蛋糕。进入斯卡拉只有2个月,所以只是刮擦表面;我没有看到任何直接的方法来解决这个问题(对于经验丰富的Scala开发人员,可能是可行的)

2 个答案:

答案 0 :(得分:5)

好消息是,Scala的产品界面由所有案例类实现,实际上并没有让这很难做到。我是一个名为Salat的Scala序列化库的作者,它提供了一些使用pickle Scala签名来获取类型字段信息的实用程序

https://github.com/novus/salat - 查看salat-util包中的一些实用程序。

实际上,我认为这是萨拉特应该做的事情 - 这是一个好主意。

Re:D.C。Sobral关于在编译时无法验证params的观点 - 在实践中这应该在运行时工作,就像反序列化其他任何不保证结构的东西一样,如JSON或Mongo DBObject。此外,Salat还有一些工具可以利用提供的默认args。

答案 1 :(得分:3)

这是不可能的,因为在编译时无法验证是否在该映射中传递了所有参数。