我开始学习Clojure,并阅读了关于结构共享的内容。在以下情况下,我感到困惑:
按照以下顺序在REPL中键入以下Clojure代码:
1) (def a [1 2 3]), 2) (def b a), 3) (def a (conj a 4)), 4) (def b (conj b 5)),
第四步之后,a和b是否共享前三个元素的结构,还是所有值都将在第四步执行时被复制?如果结构是共享的,Clojure如何能够返回我们索引3处的值?
这与 Clojure中的结构共享有些相关,但我仍然感到困惑。任何形式的帮助都将不胜感激。
1) (def a [1 2 3]), 2) (def b a), 3) (def a (conj a 4)), 4) (def b (conj b 5)),
第四步之后,a和b是否共享前三个元素的结构,还是所有值都将在第四步执行时被复制?如果结构是共享的,Clojure如何能够返回我们索引3处的值?
这与 Clojure中的结构共享有些相关,但我仍然感到困惑。任何形式的帮助都将不胜感激。
a
和b
确实不会共享任何内容。这并不意味着conj
是O(n),因为复制的数量有限(每个树级别一个包含32个对象的数组)。恰好这种操作模式非常适合缓存,并且在今天的CPU缓存大小下,使用长度小于32的数组并不能节省多少时间。支持这一说法的经验证据来自基准测试,其中向量显示出优异的性能。 - Michał Marczyka
和b
只是指向同一个向量。这不是结构共享,结构共享是指在不同向量之间共享内部树的部分;这只是将相同的值赋给两个Clojure变量的情况。(你可以类似地说(def a (java.util.HashMap.))
,放入一些条目,然后说(def b a)
。此时,a
和b
将引用相同的HashMap
,但这不是结构共享的情况;实际上,这个概念根本不适用于java.util.HashMap
。) - Michał Marczyk