我想使用瞬态来创建一个大型数据结构.这是没有瞬态的代码:
(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!).什么是更好的方法?
into 尽可能自动使用瞬变.
也就是说,首先要做的into是检查它的第一个参数是否具有瞬态版本(是否实现了`clojure.lang.IEditableCollection):
如果是,则into使用transient+ reduce+ conj!+ persistent(最重要的是,with-meta+ meta保存元数据);
否则它使用reduce+ conj.
如果您想确认详细信息,请参阅Clojure 1.8的来源.(特别要注意的是,上述所有情况都适用于采用传感器的三元过载.)
所以你的原始表达式(into [] (repeat 10 :a))已经使用了瞬态,实际上是这里使用瞬态的最佳方法.任何明确提及transient/ conj!/等完全是多余的.