在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开发人员,可能是可行的)
答案 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)
这是不可能的,因为在编译时无法验证是否在该映射中传递了所有参数。