2

在 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

显示问题可能解决方案的相关线程。

现在,据我所知,至少从 Scala 2.9.1 开始,关于案例类的反射基本上是无操作的。最终的结果似乎是一个人被迫进行某种形式的手动对象创建,考虑到 Scala 的强大功能,这有点讽刺。

我应该提到,用例涉及到 servlet 请求参数映射。具体来说,使用 Lift、Play、Spray、Scalatra 等,我想获取经过清理的参数映射(通过路由层过滤)并将其绑定到目标案例类实例,而无需手动创建对象,也无需指定其类型. 这将需要“可靠的”反射和“str2Date”之类的隐式来处理类型转换错误。

也许在带有新反射库的 2.10 中,实现上述内容将是小菜一碟。进入 Scala 才 2 个月,所以只是触及表面;我现在没有看到任何直接的方法来实现这一点(对于经验丰富的 Scala 开发人员来说,也许是可行的)

4

2 回答 2

5

好消息是,由所有案例类实现的 Scala 的 Product 接口实际上并不难做到。我是一个名为 Salat 的 Scala 序列化库的作者,该库提供了一些实用程序,用于使用腌制的 Scala 签名来获取键入的字段信息

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

实际上,我认为这是 Salat 应该做的事情——真是个好主意。

回复:DC Sobral 关于在编译时无法验证参数的观点 - 采取的点,但实际上这应该在运行时工作,就像反序列化其他任何不保证结构的东西一样,如 JSON 或 Mongo DBObject。此外,Salat 具有利用提供的默认参数的实用程序。

于 2012-01-05T19:54:39.427 回答
3

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

于 2012-01-05T19:59:42.420 回答