我已经开始学习Clojure,正在阅读有关结构共享的内容.我在以下场景中感到困惑:以下定义的序列中的clojure代码在REPL中输入:
1)(def a [1 2 3]),
2)(def b a),
3)(def a (conj a 4)),
4)(def b (conj b 5)),
在第4步之后,a和b将共享前三个元素的结构,还是在执行第4步时复制所有值?如果结构是共享的,那么Clojure如何能够在索引3处返回值?
这有点与Clojure中的结构共享有关,但我仍然感到困惑.任何形式的帮助将不胜感激.
在问题文本中给出的示例中,根本没有发生结构共享.这是因为向量是作为树实现的,其中实际元素存储在大小为32的叶节点中(最终叶子分别存储为向量的"尾部" - 性能优化),分支节点同样是32路.因此,为了使结构共享发挥作用,需要足够大的矢量:
;; a base vector:
(def v1 (vec (range 31)))
;; no structural sharing -- all elements are copied:
(def v2 (conj v1 31))
;; leftmost leaf of internal tree uses v2's tail as its internal array:
(def v3 (conj v2 32))
;; leftmost leaf shared with v3
(def v4 (conj v3 33))
Run Code Online (Sandbox Code Playgroud)
通常,每当一个conj对象进入现有向量时,新向量或者(1)与原始向量共享整个内部树,但是在原始内部树的每个级别上都有一个新尾或(2)与原始共享. ,除了最右边的节点之外的所有节点(并且可以具有比原始节点高一级的内部树).(显然,原始矢量的所有元素都与新的元素共享.)
至于通过索引查找值,它在每种情况下都以相同的方式发生 - 向量不关心它们的结构是否恰好与其他向量共享(并且没有理由为什么它们需要,因为它永远不会改变).
| 归档时间: |
|
| 查看次数: |
650 次 |
| 最近记录: |