【问题标题】:Is it possible to create circular references in Clojure?是否可以在 Clojure 中创建循环引用?
【发布时间】:2010-09-12 19:22:59
【问题描述】:

忽略本机互操作和瞬态,是否可以在 Clojure 中创建包含直接循环引用的任何数据结构?

似乎不可变的数据结构只能包含对自身先前版本的引用。是否有任何 Clojure API 可以创建引用自身的新数据结构?

Scheme 具有 letrec 形式,允许创建相互递归的结构 - 但据我所知,Clojure 没有类似的东西。

这个问题与将 Clojure 移植到 iOS 有关 - 它没有垃圾收集,但有引用计数。

【问题讨论】:

标签: clojure circular-reference


【解决方案1】:

通过将某种形式的引用放入数据结构中,然后更新引用以指向整个结构,您可以非常轻松地创建循环引用。

一个简单的例子:

(def a [(atom nil)])

(reset! (first a) a)

这将创建一个包含一个元素的列表,该元素是一个指向列表的原子。

【讨论】:

  • 感谢您的回答。我只会使用 ref 类型作为顶级对象,所以我从来没有考虑过。
  • 这是一个指向一个列表的变量,该列表指向一个引用变量的原子
  • @Arther - 从技术上讲,它是一个指向向量的 var,其中包含指向向量的原子。即 var 本身不在循环循环中。
  • 这个例子在我的环境中导致 StackOverflowError:(
【解决方案2】:

在 Clojure 中,大多数循环数据结构都会显式地通过某种类型的 ref 类型(例如 atom)。

但是你可以创建一个循环序列(这有点矛盾):

(let [a (atom nil)] (reset! a (lazy-seq (cons 1 @a))))

自从 Clojure 1.2 使用 deftype 以来,您可以创建其他可以引入循环的数据类型,而无需显式(至少来自用户代码)任何类型的 ref 类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多