2
我有以下代码,定义了一个在其中有原子的类型。在deftype中使用原子时出现奇怪的错误
(defprotocol IDeck (vec-* [dk] "Output to a persistent vector") (count-* [dk] "Number of elements in the deck") (conj1-* [dk & es] "Adding multiple elements to the deck")) (deftype ADeck [#^clojure.lang.Atom val] IDeck (vec-* [dk] (->> (.val dk) deref (map deref) vec)) (count-* [dk] (-> (.val dk) deref count)) (conj1-* [dk & es] (try (loop [esi es] (let [e (first esi)] (cond (nil? e) dk :else (do (swap! (.val dk) #(conj % (atom e))) (recur (rest esi)))))) (catch Throwable t (println t))))) (defn new-*adeck ([] (ADeck. (atom []))) ([v] (ADeck. (atom (vec (map atom v)))))) (defn conj2-* [dk & es] (try (loop [esi es] (let [e (first esi)] (cond (nil? e) dk :else (do (swap! (.val dk) #(conj % (atom e))) (recur (rest esi)))))) (catch Throwable t (println t)))) ;; Usage (def a (new-*adeck [1 2 3 4])) (count-* a) ;=> 4 (vec-* a) ;=> [1 2 3 4] (conj1-* a 1 2) ;; The deftype case ;=> IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long (vec-* a) ;=> [1 2 3 4] (conj2-* a 1 2) ;; The defn case (vec-* a) ;=> [1 2 3 4 1 2]
即使两个conj- *方法是完全一样的,不同之处在于一个处于DEFTYPE和另一个是正常DEFN,而第二个成功,则第一给出了一个错误。为什么是这样?