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

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

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

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

是不是说,LazySeq添加新项的地方就是头部?我怎样才能得到(\a \b \c \d \e)结果?

4

2 回答 2

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 被视为列表。

我怎样才能得到(\a \b \c \d \e)结果?

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

(conj (vec (drop-last "abcde"))
      (last "abcde"))
于 2012-07-15T10:13:47.120 回答
1

重要的是要意识到在 Clojure 的 Java 东西中conj简单地委托给接口cons上的实现。IPersistentCollection因此,根据正在处理的给定数据结构,它的行为可能会有所不同。

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

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

于 2012-07-17T02:57:02.540 回答