2011-04-12 20 views

Respuesta

10

Puede pasar valores iniciales a un registro bastante facilidad cuando cree que a pesar de un mapa de extensión:

(defrecord Foo []) 

(def foo (Foo. nil {:bar 1 :baz 2})) 

A la luz de esto, por lo general crear una función de constructor que se funde en algunos valores por defecto (que se puede anular como desee):

(defn make-foo [values-map] 
    (let [default-values {:bar 1 :baz 2}] 
    (Foo. nil (merge default-values values-map)))) 

(make-foo {:fiz 3 :bar 8}) 
=> #:user.Foo{:fiz 3, :bar 8, :baz 2} 
20

Utilice una función de constructor.

(defrecord Foo [a b c]) 

(defn make-foo 
    [& {:keys [a b c] :or {a 5 c 7}}] 
    (Foo. a b c)) 

(make-foo :b 6) 
(make-foo :b 6 :a 8) 

Por supuesto, hay varias variaciones. Por ejemplo, podría requerir que ciertos campos sean no opcionales y sin un valor predeterminado.

(defn make-foo 
    [b & {:keys [a c] :or {a 5 c 7}}] 
    (Foo. a b c)) 

(make-foo 6) 
(make-foo 6 :a 8) 

YMMV.

+0

enlace que explica el uso de *: teclas * y *: * o http://stuartsierra.com/2010/01/15/ keyword-arguments-in-clojure – leeor

+0

uno también podría utilizar 'map-> Foo' y/o' -> Foo' como '(defn make-foo [& args] (map-> Foo (en args {: a 5 : b 1: c 7})) (make-foo {: b 3}) '- ahorra un poco de desestructuración – birdspider

1

Después de tener la misma pregunta, terminé envolviendo el defrecord y la función de fábrica en una definición única usando una macro.

La macro:

(defmacro make-model 
    [name args & body] 
    (let [defaults (if (map? (first body)) (first body) {}) 
     constructor-name (str/lower-case (str "make-" name))] 
    `(do (defrecord ~name ~args [email protected](if (map? (first body)) (rest body) body)) 
     (defn ~(symbol constructor-name) 
      ([] (~(symbol constructor-name) {})) 
      ([values#] (~(symbol (str "map->" name)) (merge ~defaults values#))))))) 

Uso

(make-model User [firstName lastName] {:lastName "Smith"}) 
=> #'user/make-user 
(make-user {:firstName "John"}) 
=> #user.User{:firstName "John", :lastName "Smith"} 
Cuestiones relacionadas