data-structures - 从 Clojure 中的数据结构实现细节中抽象出来

标签 data-structures clojure encapsulation abstraction

我正在 Clojure 中开发具有多个子结构的复杂数据结构。

我知道随着时间的推移我会想要扩展这个结构,并且有时可能想要在不破坏数据结构的不同用户的情况下改变内部结构(例如,我可能想要将向量更改为哈希图,添加某种索引出于性能原因的结构,或合并 Java 类型)

我目前的想法是:

  • 使用各种访问器方法为整体结构定义协议(protocol)
  • 创建导航数据结构的函数的迷你库,例如(查询子结构 abc 参数 1 参数 2)
  • 使用 defrecord 或 deftype 实现数据结构,协议(protocol)方法定义为使用迷你库

  • 我认为这会起作用,尽管我担心它开始看起来像是很多“胶水”代码。此外,这可能也反射(reflect)了我对面向对象方法的更熟悉。

    在 Clojure 中推荐的方法是什么?

    最佳答案

    我认为 deftype可能是要走的路,但是我会通过访问器方法。相反,请查看 clojure.lang.ILookupclojure.lang.Associative ;这些是接口(interface),如果您为您的类型实现它们,将允许您使用 get/get-inassoc/assoc-in ,提供了一个更加通用的解决方案(您不仅可以更改底层实现,还可以使用构建在 Clojure 标准集合库之上的函数来操作您的结构)。
    有几点需要注意:

  • 您可能应该从 defrecord 开始, 使用 get , assoc & Co. 与标准 defrecord ILookup 的实现, Associative , IPersistentMapjava.util.Map .你也许可以用它走很长的路。
    如果/当这些还不够时,请查看 emit-defrecord 的来源(在 Clojure 的源代码中 core_deftype.clj 中定义的私有(private)函数)。它非常复杂,但它会让您了解您可能需要实现什么。
  • 都不是deftype也不是 defrecord目前为您定义任何工厂函数,但您可能应该自己做。健全性检查进入这些功能(和/或相应的测试)。
  • 概念上更复杂的操作当然非常适合建立在 get 基础上的协议(protocol)功能。公司

  • 哦,看看gvec.clj在 Clojure 的源代码中,有一个使用 deftype 编写的一些严肃的数据结构代码的示例。可能看起来像。这里的复杂性与您在问题中描述的不同,但它仍然是目前可供公众使用的 Clojure 中为数不多的自定义数据结构编程示例之一(当然,它是高质量的代码)。
    当然,这只是我此时的直觉告诉我的。我不确定现阶段是否有很多已建立的习语,deftype实际上并没有被释放。 :-)

    关于data-structures - 从 Clojure 中的数据结构实现细节中抽象出来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3110338/

    相关文章:

    php - 为什么不在 PHP 中使用 'protected' 或 'private'?

    python - Leetcode 90. 类型错误 : unhashable type: 'list'

    java - 结构数组总是比数组结构快?

    java - java中的堆栈比较

    algorithm - 用零标记所有列和行

    amazon-web-services - 使用 Leiningen 通过 Gulp 构建前端

    clojure - 将 Java 方法作为参数传递

    java - 实现不违反封装的 OOP 委托(delegate)

    clojure - Clojure 中 use 和 require 之间的区别

    c++ - 如何在不创建 "friend"的情况下访问类外的私有(private)数据成员?