そこにアトムを持つ型を定義する次のコードがあります。
(defprotocol IDeck (vec-* [dk] "永続ベクトルへの出力") (count-* [dk] "デッキ内の要素数") (conj1-* [dk & es] "デッキに複数の要素を追加する")) (deftype ADeck [#^clojure.lang.Atom val] IDeck (vec-* [dk] (->> (.val dk) deref (map deref) vec)) (count-* [dk] (-> (.val dk) deref count)) (conj1-* [dk & es] (試す (ループ [ES] (let [e (最初の esi)] (状態 (なし? e) dk :そうしないと (行う (swap! (.val dk) #(conj % (atom e))) (繰り返し (残りの esi)))))) (catch Throwable t (println t))))) (defn new-*adeck ([] (ADeck. (atom []))) ([v] (ADeck. (atom (vec (map atom v)))))) (defn conj2-* [dk & es] (試す (ループ [ES] (let [e (最初の esi)] (状態 (なし? e) dk :そうしないと (行う (swap! (.val dk) #(conj % (atom e))) (繰り返し (残りの esi)))))) (catch Throwable t (println t)))) ;; 使用法 (def a (new-*adeck [1 2 3 4])) (count-* a) ;=> 4 (vec-* a) ;=> [1 2 3 4] (conj1-* a 1 2) ;; deftype ケース ;=> IllegalArgumentException java.lang.IllegalArgumentException: 次から ISeq を作成する方法がわかりません: java.lang.Long (vec-* a) ;=> [1 2 3 4] (conj2-* a 1 2) ;; 定義されたケース (vec-* a) ;=> [1 2 3 4 1 2]
2 つの conj-* メソッドはまったく同じですが、1 つは deftype で、もう 1 つは通常の defn であることを除いて、最初のメソッドはエラーを返し、2 番目のメソッドは成功します。どうしてこれなの?