use*_*354 5 json scala immutability case-class playframework
我正在阅读结构化JSON,使用Play Frameworks的JSON Reads来构建带有案例类的对象图.
一个例子:
case class Foo (
id: Int,
bar_id: Int,
baz_id: Int,
x: Int,
y: String
)
{
var bar: Bar = null
var baz: Baz = null
}
Run Code Online (Sandbox Code Playgroud)
在建造Foo之后,我必须稍后回来并通过设置bar和baz来装饰它.这些在其他JSON文件中定义,仅在所有解析完成时才知道.但这意味着Foo不可能是不可变的.
Scala中制作不可变对象的"正确"方式是什么,然后是它的装饰版本,而不是一遍又一遍地重复Foo的每个字段?
我知道几种感觉错误的方法:
当然,Scala必须有办法让人们用更简单的对象组成更复杂的不可变对象,而不必手工复制它们的每一部分?
组合Option和输入参数,您可以标记您的案例类,并静态跟踪处理的字段是否为空:
import scala.language.higherKinds
object Acme {
case class Foo[T[X] <: Option[X] forSome { type X }](a: Int,
b: String,
c: T[Boolean],
d: T[Double])
// Necessary, Foo[None] won't compile
type Unprocessed[_] = None.type
// Just an alias
type Processed[X] = Some[X]
}
Run Code Online (Sandbox Code Playgroud)
示例用例:
import Acme._
val raw: Foo[Unprocessed] = Foo[Unprocessed](42, "b", None, None)
def process(unprocessed: Foo[Unprocessed]): Foo[Processed] =
unprocessed.copy[Processed](c = Some(true), d = Some(42d))
val processed: Foo[Processed] = process(raw)
// No need to pattern match, use directly the x from the Some case class
println(processed.c.x)
println(processed.d.x)
Run Code Online (Sandbox Code Playgroud)
我在当前的项目中使用过一次。我遇到的主要问题是当我想要Foo协变时。
或者,如果您不关心 的界限T:
case class Foo[+T[_]](a: Int, b: String, c: T[Boolean], d: T[Double])
Run Code Online (Sandbox Code Playgroud)
那么你可以在需要时使用Foo[Unprocessed]or 。Foo[Processed]Foo[Option]
scala> val foo: Foo[Option] = processed
foo: Acme.Foo[Option] = Foo(42,b,Some(true),Some(42.0))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
399 次 |
| 最近记录: |