为什么我不能在 Clojure 中查看排序序列?

问题描述 投票:0回答:1

在练习 Clojure 时我注意到了这一点。偷看一个矢量按预期工作:

(let [v (vector 1 2 3)]
  (peek v))
;; => 3

也偷看一个列表:

(let [l (list 1 2 3)]
  (peek l))
;; => 1

但是,如果我首先对序列进行sort,它会恐慌!

(let [l (sort (list 1 2 3))]
  (peek l))

;; => Unhandled java.lang.ClassCastException
   class clojure.lang.ArraySeq cannot be cast to class
   clojure.lang.IPersistentStack (clojure.lang.ArraySeq and
   clojure.lang.IPersistentStack are in unnamed module of loader
   'app')

为什么会这样? 谢谢!

clojure
1个回答
-1
投票

简答

peek
函数仅适用于 stack。在 Clojure 中,
vector
list
都可以用作堆栈。对于任何其他序列类型,只需使用
first
获取初始元素。


更多详情

如果你阅读了 Clojure 源代码,它使用了内置的 Java 排序算法:

(defn sort
  "Returns a sorted sequence of the items in coll. If no comparator is
  supplied, uses compare.  comparator must implement
  java.util.Comparator.  Guaranteed to be stable: equal elements will
  not be reordered.  If coll is a Java array, it will be modified.  To
  avoid this, sort a copy of the array."
  {:added "1.0"
   :static true}
  ([coll]
   (sort compare coll))
  ([^java.util.Comparator comp coll]
   (if (seq coll)
     (let [a (to-array coll)]
       (. java.util.Arrays (sort a comp))
       (with-meta (seq a) (meta coll)))
     ())))

函数

to-array
“映射到java.util.Collection.toArray()”。您可以在错误消息
class clojure.lang.ArraySeq cannot be cast...
中看到这一点的提示。
peek
函数仅对 Clojure 类型进行操作,而
sort
返回不同的类型。

您可以检查 Clojure 类型具有的超类和接口,如下所示:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(verify
  (is= clojure.lang.ArraySeq (type (sort [1 2 3])))

  (is= (parents clojure.lang.ArraySeq)
    #{clojure.lang.ASeq
      clojure.lang.IReduce
      clojure.lang.IndexedSeq})

  (is= (ancestors clojure.lang.ArraySeq)
    #{clojure.lang.ASeq
      clojure.lang.Counted
      clojure.lang.IHashEq
      clojure.lang.IMeta
      clojure.lang.IObj
      clojure.lang.IPersistentCollection
      clojure.lang.IReduce
      clojure.lang.IReduceInit
      clojure.lang.ISeq
      clojure.lang.IndexedSeq
      clojure.lang.Obj
      clojure.lang.Seqable
      clojure.lang.Sequential
      java.io.Serializable
      java.lang.Iterable
      java.lang.Object
      java.util.Collection
      java.util.List})
  )

使用这个模板项目.

© www.soinside.com 2019 - 2024. All rights reserved.