/ / Dans Clojure, comment puis-je implémenter des interfaces de collection Clojure standard sur mes propres enregistrements et types? - clojure

Dans Clojure, comment puis-je implémenter des interfaces de collection Clojure standard sur mes propres enregistrements et types? - clojure

Je souhaite créer une abstraction qui représente une table de base de données, mais qui peut être consultée à l’aide de tous les objets Clojure seq and conj habituels, ainsi que de tous ces trucs sophistiqués. Dois-je ajouter un protocole?

Réponses:

15 pour la réponse № 1

Oui. Le protocole est défini par l'interface Java clojure.lang.ISeq. Vous voudrez peut-être prolonger clojure.lang.ASeq qui en fournit une implémentation abstraite.

Voici un exemple: a seq abstraction d’une ressource qui peut être fermée et qui se ferme automatiquement lorsque le seq prend fin. (Pas rigoureusement testé)

(deftype CloseableSeq [delegate-seq close-fn]
clojure.lang.ISeq
(next [this]
(if-let [n (next delegate-seq)]
(CloseableSeq. n close-fn)
(.close this)))
(first [this] (if-let [f (first delegate-seq)] f (.close this)))
(more [this] (if-let [n (next this)] n "()))
(cons [this obj] (CloseableSeq. (cons obj delegate-seq) close-fn))
(count [this] (count delegate-seq))
(empty [this] (CloseableSeq. "() close-fn))
(equiv [this obj] (= delegate-seq obj))
clojure.lang.Seqable
(seq [this] this)
java.io.Closeable
(close [this] (close-fn)))