是否可以在Clojure中创建循环引用?

Nic*_*ain 22 clojure circular-reference

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

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

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

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

mik*_*era 14

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

一个简单的例子:

(def a [(atom nil)])

(reset! (first a) a)
Run Code Online (Sandbox Code Playgroud)

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

  • 此示例导致我的环境中的StackOverflowError :( (2认同)

cgr*_*and 8

在Clojure中,大多数循环数据结构将明确地通过某种类型的ref类型(例如atom).

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

(let [a (atom nil)] (reset! a (lazy-seq (cons 1 @a))))
Run Code Online (Sandbox Code Playgroud)

而且由于Clojure 1.2带有deftype,你可以创建其他数据类型,这些数据类型可以引入循环,而不必明确地使用任何类型的ref类型(至少来自用户代码).