【问题标题】:How could an idiomatic design of Serializable/Cloneable/... look like in Scala?Serializable/Cloneable/... 的惯用设计怎么会像 Scala 中的那样?
【发布时间】:2011-09-13 03:47:57
【问题描述】:

我想知道如果 Scala 不(必须)遵循 Java 的 java.io.Serializable/java.lang.Cloneable(主要是为了与 Java 和工具/生态系统)。

由于 Scala 在语言设计上更简单,但实现了更强大的实现和抽象可能性,因此可以想象 Scala 可能会走一条与 Java 不同的道路,如果它不必承担 Java 兼容性负担的话。

我可以想象一个惯用的实现会使用带有(可能)私有字段/方法的类型类或特征(在 Java 接口中不可能?),也许带有一些标准实现?

或者标记接口在 Scala 中仍然是正确的选择吗?

【问题讨论】:

  • 需要注意的一点是,case classes 很容易用他们的copy 方法克隆,这也允许在复制时重新定义一些值。
  • java中的可克隆和可序列化完全不同,Object.clone()只是一个memcpy(或多或少)但序列化是完整的对象图遍历。
  • 是的,我知道。问题是关于这些“魔法”类本身,我不想暗示它们是相关的。

标签: java scala serialization language-design


【解决方案1】:

由于可变性,序列化和克隆都是特殊的:

  • 序列化,因为它必须处理对象图中的循环,并且;
  • 克隆是因为...嗯,克隆对象的唯一原因是防止可变状态的意外传播。

因此,如果您愿意提交一个完全不可变的域模型,那么您将不再拥有对象图,而是拥有对象树。

对于面向功能的序列化方法,SBinary 是我可能首先尝试的方法。对于克隆,不要这样做。 :)

【讨论】:

    【解决方案2】:

    或者标记接口在 Scala 中仍然是正确的选择吗?

    不。它们甚至不是 Java 中的正确选择。它们应该是注解,而不是接口。

    【讨论】:

    • 但是注释不会被继承,对吧?这不是意味着注释机制必须复制语言的继承规则吗?
    • 另外,据我所知,注释不允许编译时检查,例如def foo(arg:Cloneable)
    • @x3ro 不是这样。 cpsParam 是一个反例。不过,我相信特定于注解的类型检查逻辑必须在编译器插件中实现(或添加到类型器中)。您不能只创建一个派生自 TypeConstraint 的注释。
    【解决方案3】:

    在 ideomatic scala 中执行此操作的最佳方法是使用具有类型类效果的隐式。 这用于 Ordered 特征

    def max[A <% Ordered[A]](a:A,b:A); 
    

    意思同:

    def max[A](a:A,b:A)(implicit orderer: T => Ordered[A]);
    

    它说你可以使用所有类型 A,只要它可以作为 Ordered[A] 受到威胁。 这具有 Java 的接口/继承方法所没有的几个好处

    1. 您可以将隐式有序定义添加到现有类型。你不能用继承来做到这一点。

    2. 一个类型可以有多个 Ordered 实现!这比 Haskell 中的 Type 类更加灵活,Haskell 中每个类型只允许一个实例。

    总之,scalas 隐式与泛型一起使用可以非常灵活地在类型上定义约束。

    与可克隆/可序列化相同。

    您可能还想查看 scalaz 库,它为 Scala 添加了类似 Haskell 的类型类,例如 Functor、Applicative 和 Monad,并提供了一组丰富的隐式,因此这些概念也可以丰富标准库。

    【讨论】:

    • 投反对票:您正在混淆视图边界和上下文边界,以及 OrderedOrdering。请阅读此内容并更新您的答案:stackoverflow.com/questions/4465948/…。此外,您没有讨论更具体的克隆和序列化问题,例如继承和重用超类的克隆和序列化功能等。
    猜你喜欢
    • 2011-09-13
    • 2020-04-04
    • 2011-09-20
    • 2011-06-09
    • 1970-01-01
    • 2011-06-06
    • 2016-05-19
    • 2019-08-21
    • 1970-01-01
    相关资源
    最近更新 更多