为何无法在Clojure中对排序后的序列执行peek操作?
异常原因分析
核心原因
peek 函数仅支持实现了clojure.lang.IPersistentStack接口的集合类型,而sort的返回值并不属于这类集合。
细节拆解
Vector和List都是Clojure中实现了IPersistentStack的核心集合,所以直接对它们调用peek可以正常工作:(let [v (vector 1 2 3)] (peek v)) ; => 3 (let [l (list 1 2 3)] (peek l)) ; => 1sort函数的内部逻辑是将输入序列转换为数组完成排序,最终返回的是clojure.lang.ArraySeq类型的对象。ArraySeq只是一个基础的序列实现,没有实现IPersistentStack接口。- 当你对
ArraySeq调用peek时,Clojure会尝试将其强制转换为IPersistentStack类型,这就直接触发了ClassCastException异常。
验证与解决办法
可以通过类型检查确认返回值:
(type (sort (list 1 2 3))) ; => clojure.lang.ArraySeq
如果需要对排序后的结果调用peek,只需将sort的返回值转换为List或Vector即可:
;; 转换为List (peek (apply list (sort (list 1 2 3)))) ; => 3 ;; 转换为Vector (peek (vec (sort (list 1 2 3)))) ; => 3
内容的提问来源于stack exchange,提问作者Alessandro Bertulli
相关产品推荐
相关产品推荐

