使用`repeat`创建瞬态数据结构

Chr*_*phy 0 clojure

我想使用瞬态来创建一个大型数据结构.这是没有瞬态的代码:

(into [] (repeat 10 :a))
;; => [:a :a :a :a :a :a :a :a :a :a]
Run Code Online (Sandbox Code Playgroud)

我天真的尝试是这样的:

(persistent! (into (transient []) (repeat 10 :a)))
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式获取错误消息:

(into (transient []) (repeat 10 :a))
;; => ClassCastException clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentCollection  clojure.core/conj--6410 (core.clj:82)
Run Code Online (Sandbox Code Playgroud)

试图使用是不对的repeat?(没有这样的功能repeat!).什么是更好的方法?

Mic*_*zyk 6

into 尽可能自动使用瞬变.

也就是说,首先要做的into是检查它的第一个参数是否具有瞬态版本(是否实现了`clojure.lang.IEditableCollection):

  1. 如果是,则into使用transient+ reduce+ conj!+ persistent(最重要的是,with-meta+ meta保存元数据);

  2. 否则它使用reduce+ conj.

如果您想确认详细信息,请参阅Clojure 1.8的来源.(特别要注意的是,上述所有情况都适用于采用传感器的三元过载.)

所以你的原始表达式(into [] (repeat 10 :a))已经使用了瞬态,实际上是这里使用瞬态的最佳方法.任何明确提及transient/ conj!/等完全是多余的.