【发布时间】:2015-04-26 04:01:12
【问题描述】:
我正在阅读结构化 JSON,使用 Play Frameworks 的 JSON 读取来构建带有案例类的对象图。
一个例子:
case class Foo (
id: Int,
bar_id: Int,
baz_id: Int,
x: Int,
y: String
)
{
var bar: Bar = null
var baz: Baz = null
}
在构建 Foo 之后,我必须稍后再回来通过设置 bar 和 baz 来装饰它。这些是在其他 JSON 文件中定义的,并且仅在所有解析完成时才知道。但这意味着 Foo 不能是不可变的。
在 Scala 中创建不可变对象的“正确”方法是什么,然后是它的修饰版本,而不是多次重复 Foo 的每个字段,一遍又一遍?
我知道有几种感觉不对劲的地方:
- 制作 "bar: Option[Bar]" 和 "baz: Option[Baz]" 案例类参数,然后我可以使用 "copy" 制作新版本的 Foo 类,并将它们设置为某个值;但是每次访问它们时我都必须检查它们 - 效率低下,不安全,无法制作保证具有正确结构的 DecoratedFoo
- 创建第二个案例类,它是第一个中所有结构的复制粘贴,但添加了两个额外的修饰参数 - 但这意味着在定义中回显整个参数列表,并在创建它的实例时再次
- 案例类继承显然是有争议的,而且无论如何似乎也要求我在子类构造函数中重复每个参数?
- 创建一个非案例超类,列出常见案例类参数。然后在案例类中扩展它。但这似乎仍然需要在子类构造函数中重复每个参数。
- 我看到有人谈论这个问题并在运行时使用反射来填充其修饰副本的基本属性的博客 - 这可以避免回显,但现在您没有类型安全性,将属性名称指定为字符串、开销等...
Scala 肯定有办法让人们从简单的对象中组合出更复杂的不可变对象,而不必手动复制它们的每一部分?
【问题讨论】:
-
这也是我的痛点。在我看来,一般问题是声明一个核心数据模型,然后以 DRY 的方式定义作为原始模型转换的派生/增强模型。到目前为止,我还没有找到该问题的通用解决方案。
标签: json scala playframework immutability case-class