gpt4 book ai didi

json - 如何从 scala 案例类中装饰不可变对象(immutable对象)图

转载 作者:行者123 更新时间:2023-12-04 20:39:40 26 4
gpt4 key购买 nike

我正在阅读结构化 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
}

构建 Foo 后,我必须稍后再回来通过设置 bar 和 baz 来装饰它。这些是在其他 JSON 文件中定义的,并且仅在所有解析完成时才知道。但这意味着 Foo 不能是不可变的。

在 Scala 中创建不可变对象(immutable对象)的“正确”方法是什么,然后是它的修饰版本,而不是一遍又一遍地重复 Foo 的每个字段?

我知道几种感觉不对的方式:
  • 制作 "bar: Option[Bar]"和 "baz: Option[Baz]"案例类参数,然后我可以使用 "copy"制作 Foo 类的新版本,并将它们设置为某些东西;但是每次访问它们时我都必须检查它们 - 效率低下,不安全,无法制作保证具有正确结构的 DecoratedFoo
  • 创建第二个案例类,它是第一个中所有结构的复制粘贴,但添加了两个额外的修饰参数 - 但这意味着在定义中回显整个参数列表,并在创建它的实例时再次
  • 案例类继承显然是有争议的,无论如何似乎也要求我在子类构造函数中重复每个参数?
  • 制作一个列出常见案例类参数的非案例父类(super class)。然后在案例类中扩展它。但这似乎仍然需要在子类构造函数中重复每个参数。
  • 我看到人们讨论这个问题并在运行时使用反射来填充其修饰副本的基本属性的博客——这避免了回显,但现在你没有类型安全,将属性名称指定为字符串、开销等...

  • Scala 肯定有办法让人们用更简单的不可变对象(immutable对象)组合更复杂的不可变对象(immutable对象),而不必手动复制它们的每一部分?

    最佳答案

    您可以为处理后的类型引入一个新特征、扩展该特征的类和隐式转换:

    case class Foo(bar: Int)

    trait HasBaz {
    val baz: Int
    }

    class FooWithBaz(val foo: Foo, val baz: Int) extends HasBaz

    object FooWithBaz {
    implicit def innerFoo(fwb: FooWithBaz): Foo = fwb.foo

    implicit class RichFoo(val foo: Foo) extends AnyVal {
    def withBaz(baz: Int) = new FooWithBaz(foo, baz)
    }
    }

    那么你可以这样做:
    import FooWithBaz._
    Foo(1).withBaz(5)

    而且,虽然 withBaz返回 FooWithBaz ,我们可以将返回值视为 Foo必要时,因为隐式转换。

    关于json - 如何从 scala 案例类中装饰不可变对象(immutable对象)图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28697346/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com