user=> (rseq [:a :b])
(:b :a)
user=> (rseq (rseq [:a :b]))
ClassCastException clojure.lang.APersistentVector$RSeq cannot be cast to
clojure.lang.Reversible clojure.core/rseq (core.clj:1532)
为什么rseq
无法接受之前调用rseq
的结果?
我在docstring中读到参数必须是(实际上,“可以是”)一个向量或有序映射,而上面显示它不能是RSeq
,所以我已经知道了那。我想知道的是:有这个限制的充分理由吗?这只是一种疏忽,还是这种限制提供了一些重要的好处?
此外,除了从不调用rseq
之外,还有一个方便的解决方法吗?很难知道,当你从一个函数返回RSeq
时,其他某个函数是否可以在其上调用rseq
。
我在问,因为看到我的代码因为这种令人惊讶的原因s而抛出异常令人沮丧。如果我知道为什么这有意义,我可能不太可能犯这种和类似的错误。
答案 0 :(得分:4)
你不能在seq上调用rseq
,因为你需要一个输入集合,可以随机访问fullfill rseq
的常量性能特性,而seqs只提供有效的访问(迭代)从头朝下。
对rseq
的结果调用rseq
不能特殊地返回原始集合,因为原始集合永远不是seq。如果在RSeq上调用rseq
会返回(seq coll)
的内容,则不会直接支持(rseq (drop x (rseq coll)))
。可能是那些使语言实现者无法支持“递归”rseq的并发症。
如果您需要一般的反转功能,请使用reverse
- 这将更慢。如果可以,您可能只想保留对(seq coll)
和(rseq coll)
的引用,如果您需要的话。
答案 1 :(得分:3)
因为rseq
仅适用于特殊的可逆序列。但其应用的结果是普通的seq。您始终可以检查rseq
带有reversible?
谓词的序列:
(defn reverse* [s]
(if (reversible? s)
(rseq s)
(reverse s)))
为什么这个后备不在rseq
(或reverse
)函数本身?原因是我认为rseq
应该保证其执行时间的可预测性。
如果您确实需要稍后撤回收藏,最好将其保存为矢量,例如:(rseq (vec (rseq [1 2 3])))