gpt4 book ai didi

clojure - 在 Clojure 中,何时应该使用记录或向量来表示异构节点类型的树?

转载 作者:行者123 更新时间:2023-12-02 14:48:19 25 4
gpt4 key购买 nike

对于表示由不同节点类型组成的树,哪种更好的惯用 clojure 实践:

A.使用 deftype 或 defrecord 定义的几种不同类型的记录构建树:

(defrecord node_a [left right])
(defrecord node_b [left right])
(defrecord leaf [])

(def my-tree (node_a. (node_b. (leaf.) (leaf.)) (leaf.)))

B.用向量构建树,并使用指定类型的关键字:

(def my-tree [:node-a [:node-b :leaf :leaf] :leaf])

我看到的大多数 clojure 代码似乎都倾向于使用通用数据结构(向量、 map 等),而不是数据类型或记录。举个例子,Hiccup 使用向量 + 关键字的方法很好地表示了 html。

我们什么时候应该选择一种风格而不是另一种风格?

最佳答案

您可以将任意数量的元素放入向量中。一条记录有一定数量的字段。如果你想限制你的节点只有 N 个子节点,记录可能会很好,例如当二叉树时,节点必须只有左和右。但对于 HTML 或 XML 之类的内容,您可能希望支持任意数量的子节点。

使用向量和关键字意味着“扩展”支持的节点类型集就像将新关键字放入向量中一样简单。 [:frob "foo"] 在 Hiccup 中是可以的,即使它的作者从未听说过 frobing。使用记录,您可能必须为每个节点类型定义一个新记录。但随后您将获得捕获拼写错误和验证子节点的好处。 [:strnog "some bold text?"] 不会被 Hiccup 捕获,但 (Strnog. "foo") 将是一个编译时错误。

向量是 Clojure 的基本数据类型之一,您可以使用 Clojure 的内置函数来操作它们。想扩展你的树吗?只需conj到它上面,或者update-in,或者其他什么。您可以通过这种方式逐步构建您的树。对于记录,您可能会陷入构造函数调用的困境,否则您必须为构造函数编写大量包装函数。

似乎这部分可以归结为动态与静态的争论。就我个人而言,我会采用动态(向量+关键字)路线,除非有特定需要使用记录的好处。以这种方式编码可能更容易,并且对用户来说更灵活,但代价是用户更容易最终陷入困惑。但 Clojure 用户可能习惯于定期处理危险武器。 Clojure 在很大程度上是一种动态语言,保持动态通常是正确的做法。

关于clojure - 在 Clojure 中,何时应该使用记录或向量来表示异构节点类型的树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4101614/

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