online - El registro de Clojure-¿Cómo usarlo?
clojure web framework (2)
Así es como define su registro:
(defrecord MyType [a b])
Tenga en cuenta que en Clojure no suele definir "métodos" dentro de su propio tipo de registro (la excepción es si desea implementar directamente una interfaz Java o un protocolo).
Un constructor básico (prefijado con ->
) se genera automáticamente de forma gratuita:
(def foo (->MyType [1 2 3] [4 5 6]))
foo
=> #user.MyType{:a [1 2 3], :b [4 5 6]}
Luego puede escribir funciones de constructor más sofisticadas que usan esto, por ejemplo,
(defn mytype-with-length [n]
(let [a (vec (range n))
b (vec (range n))]
(->MyType a b)))
(mytype-with-length 3)
=> #user.MyType{:a [0 1 2], :b [0 1 2]}
Y "mutate-and-return" también es gratis, solo puede usar assoc :
(assoc foo :b [7 8 9])
=> user.MyType{:a [1 2 3], :b [7 8 9]}
Estoy intentando crear mi propio tipo de datos / métodos inmutables con defrecord
en Clojure. El objetivo es tener un tipo de datos del que pueda crear instancias y luego llamar a sus métodos para devolver una nueva copia de sí misma con variables mutadas. Decir ayb son vectores. Me gustaría actualizar un valor en ambos y devolver una copia nueva de toda la estructura con esos vectores actualizados. Esto obviamente no se compila, solo estoy tratando de hacer llegar mis ideas.
(defrecord MyType [a b]
(constructor [N]
; I''d like to build an initial instance, creating a and b as vectors of length N
)
(mutate-and-return []
; I''d like to mutate (assoc the vectors) and return the new structure, a and b modified
)
)
Me gustaría llamar al constructor y luego al mutador tantas veces como me gustaría (hay otras funciones que no mutan, pero no quiero hacerlo más complejo para la pregunta).
Alternativamente, si esto no es un Clojure idiomático, ¿cómo se supone que debes hacer algo como esto?
Ejemplo de Clojure Defrecord:
; definir registro de dirección
(defrecord Address [city state])
;; define persona record
(defrecord Person [firstname lastname ^Address address])
;; buid el constructor
(defn make-person ([fname lname city state]
(->Person fname lname (->Address city state))))
;; crear una persona
(def person1 (make-person "John" "Doe" "LA" "CA"))
;; recuperar valores
(:firstname person1)
(:city (:address person1))