Desidero creare un'astrazione che rappresenti una tabella di database, ma a cui è possibile accedere utilizzando tutti i soliti Clojure seq e conj e tutto ciò che è di fantasia. C'è un protocollo che devo aggiungere?In Clojure come posso implementare interfacce di raccolta Clojure standard sui miei record e tipi?
Q
In Clojure come posso implementare interfacce di raccolta Clojure standard sui miei record e tipi?
18
A
risposta
15
Sì. Il protocollo è definito dall'interfaccia Java clojure.lang.ISeq
. Si consiglia di estendere clojure.lang.ASeq
che fornisce un'implementazione astratta di esso.
Ecco un esempio: un'astrazione seq
di una risorsa che è chiudibile e viene chiusa automaticamente quando termina lo seq
. (Non rigorosamente testato)
(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)))
Problemi correlati
- 1. Corrispondenza del modello sui record in Clojure
- 2. Mappe e record di uguaglianza in Clojure
- 3. Tipi annidati in clojure?
- 4. Documentazione di record in clojure
- 5. sincronizzazione dell'output standard Clojure
- 6. Posso aggiungere campi ai tipi di clojure?
- 7. Standard per Clojure?
- 8. È buona norma per un record Clojure implementare IFn?
- 9. Come implementare un'interfaccia Java in Clojure
- 10. Come implementare un ciclo For in Clojure
- 11. Devo implementare l'interfaccia Seq in clojure
- 12. Come implementare l'autenticazione utente usando clojure-liberator?
- 13. Risoluzione di chiamata protocollo Clojure quando classe implementa diverse interfacce
- 14. Clojure Editor scritto in Clojure
- 15. Come incapsulare in clojure?
- 16. Utilizzare le interfacce Clojure in un progetto di libreria Java
- 17. = e == in Clojure
- 18. Posso creare uno stato mutabile nei record Clojure?
- 19. Come si possono implementare le chiavi composite in clojure?
- 20. Come implementare lambda come una funzione chiamata "lambda" in Clojure?
- 21. Come posso mappare una macro in Clojure?
- 22. Come disambiguare in Clojure
- 23. Come scrivere il protocollo monoid in Clojure?
- 24. Come agganciare in Clojure
- 25. Ridefinire i campi di un record in Clojure
- 26. Posso usare Clojure con nginx?
- 27. Modificare il file di codice sorgente Clojure in clojure
- 28. Consumo WSDL in Clojure
- 29. Clojure: = vs ==
- 30. Eccezioni personalizzate in Clojure?
C'è un motivo per cui un vettore di record è insufficiente come rappresentazione? (Voglio dire questo come una domanda seria, non snark). Tutte le API di chiusura funzionerebbero con una tale astrazione. Dalla logica di clojure http://clojure.org/rationale - "È meglio avere 100 funzioni che operano su una struttura dati piuttosto che 10 funzioni su 10 strutture dati". - Alan J. Perlis –
Il motivo è che quando aggiungo un elemento al vettore voglio che l'elemento sia automaticamente conservato su un datastore, e non c'è modo che possa nasconderlo senza reimplementare conj o cons o qualsiasi altra cosa sia la funzione add. per i vettori. – Zubair
Sii super, super attento con questo genere di cose. Se DB non è immutabile, stai mentendo sulla tua semantica a Clojure, questo può andare storto molto velocemente. La maggior parte di Clojure si basa sull'idea che le collezioni sono immutabili. In questo modo vengono formulate molte ipotesi su come funzionano determinate funzioni. Ad esempio, l'uso di conj su una collezione non dovrebbe modificare la collezione. Dovrebbe restituire una nuova collezione. La violazione di questa regola potrebbe far fallire le funzioni di Clojure in modi molto strani. –