Forse stai cercando i documenti?
(require '[clojure.set :as cset])
(defrecord Person [name age address phone email])
;; Make a keyword-based constructor to verify
;; args and decouple ordering.
(let [valid #{:name :age :address :phone :email}]
(defn mk-person[& args]
(let [h (apply hash-map args)
invalid (cset/difference (set (keys h)) valid)]
(when-not (empty? invalid)
(throw (IllegalArgumentException. (pr-str invalid))))
; any other argument validation you want here
(Person.
(:name h) (:age h) (:address h) (:phone h) (:email h)))))
=> (def p (mk-person :name "John" :email "[email protected]"))
#:user.Person{:name "John", :age nil, :address nil, :phone nil,
:email "[email protected]"}
Ora è possibile scegliere se si desidera eccezioni per i nomi di errori di battitura accedendo ai dati con le funzioni (eccezione) o parole chiave (non eccezione).
=> (.fax p)
java.lang.IllegalArgumentException:
No matching field found: fax for class user.Person
=> (:fax p)
nil
Questo approccio richiede che vengano evitati i nomi di campo che sarebbero in conflitto con i metodi esistenti. (Vedi commento da @Jouni.)
In alternativa, è possibile ignorare la limitazione nome del campo utilizzando le parole chiave per la ricerca e una funzione di accesso che verifica la presenza di chiavi non valide:
(defn get-value [k rec]
(let [v (k rec ::not-found)]
(if (= v ::not-found)
(throw (IllegalArgumentException. (pr-str k)))
v)))
=> (get-value :name p)
"John"
=> (get-value :fax p)
IllegalArgumentException: :fax
"destrutturazione del torto parte della lista "problemi di tipo possono venire dal tentativo di codificare qualcosa come" persona "in una lista; quindi devi ricordare cose come "il codice postale è il quarto elemento nell'elenco" indirizzo "nella terza posizione nell'elenco" Persona ".
In Lisp "classico" si potrebbe risolvere scrivendo le funzioni di accesso, in Clojure è possibile utilizzare i record.
I tipi causano problemi in qualsiasi linguaggio di programmazione, il meglio che puoi fare è cercare di catturarli prima.
Un IDE Java con completamento automatico potrebbe rilevare alcuni refusi durante la digitazione e un linguaggio tipizzato in modo statico ne catturerà molti in fase di compilazione, ma in un linguaggio dinamico non li troverete fino al runtime. Alcune persone considerano questo un inconveniente dei linguaggi dinamici (inclusi Python, Ruby ecc.), Ma data la loro popolarità, alcuni programmatori ritengono che la flessibilità ottenuta e il codice salvato siano più importanti della perdita di errori di completamento automatico e compilazione di IDE.
Il principio è lo stesso in entrambi i casi: le eccezioni precedenti sono migliori, poiché c'è meno codice da attraversare per trovare la causa. Idealmente la traccia dello stack ti porterebbe direttamente all'errore di battitura. In Clojure, le funzioni di registrazione e accesso ti danno questo.
Dato che questo è stato pubblicato, core.typed è stato rilasciato e può anche fare la stessa cosa http://typedclojure.org/ – Ben