有人可以解释" conj&#34 ;?的行为

时间:2012-07-15 09:31:22

标签: clojure

(conj (drop-last "abcde") (last "abcde"))

返回(\e \a \b \c \d)

我很困惑。在conj的文档中,我注意到了

  

“添加”可能发生在不同的“地方”,具体取决于具体类型。

这对于LazySeq是否意味着添加新项目的位置是头? 我如何得到(\a \b \c \d \e)作为结果?

2 个答案:

答案 0 :(得分:6)

  

''添加'可能发生在不同的“地方”,具体取决于   具体类型。'

这指的是Clojure持久性集合的行为,它以最有效的方式在性能和底层实现方面加入了这一特性。

向量总是添加到集合的末尾:

user=> (conj [1 2 3] 4)
[1 2 3 4]

使用Lists,如您所注意到的那样,conj将项目放在列表的前面:

user=> (conj '(1 2 3) 4)
(4 1 2 3)

所以,是的,就其具体实现而言,LazySeq被视为List。

  

如何获得(\a \b \c \d \e)作为结果?

有很多种方法,但您可以轻松地从LazySeq创建一个矢量:

(conj (vec (drop-last "abcde"))
      (last "abcde"))

答案 1 :(得分:1)

重要的是要意识到conj只是委托在Clojure的Java内容中cons接口上IPersistentCollection的实现。因此,根据所处理的给定数据结构,它可以表现不同。

conj背后的意图是它总是以最有效的方式将数据添加到数据结构中。

对于列表,最有效的位置是前面。对于向量,最有效的位置是最终的。