Clojure的defrecord - 如何使用它? [英] Clojure's defrecord - how to use it?
问题描述
我试图在Clojure中使用 defrecord
创建我自己的不可变数据类型/方法。目标是有一个数据类型,我可以创建的实例,然后调用其方法来返回一个带有变量变量的新副本。说a和b是向量。我想更新一个值,并返回一个新的副本的整个结构与这些向量更新。这显然不编译,我只是想得到我的想法。
I'm attempting to create my own immutable datatype/methods with defrecord
in Clojure. The goal is to have a datatype that I can create instances of, and then call its methods to return a new copy of itself with mutated variables. Say a and b are vectors. I'd like to update a value in both and return a new copy of the entire structure with those vectors updated. This obviously doesn't compile, I'm just trying to get my ideas across.
(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
)
)
我想调用构造函数,然后调用mutator多次,我想要的(还有其他函数不变异,但我
I'd like to call the constructor and then the mutator as many times as I'd like (there are other functions that don't mutate, but I don't want to make it more complex for the question).
或者,如果这不是惯用的Clojure,你应该怎么做这样的事情?
Alternatively, if this is not idiomatic Clojure, how are you supposed to do something like this?
推荐答案
以下是您如何定义记录:
Here's how you define your record:
(defrecord MyType [a b])
请注意,在Clojure中,
Note that in Clojure you don't typically define "methods" within your record type itself (the exception is if you want to directly implement a Java interface or a protocol).
一个基本的构造函数(以<$ c为前缀) $ c> - > )免费自动生成:
A basic constructor (prefixed with ->
) gets generated automatically for free:
(def foo (->MyType [1 2 3] [4 5 6]))
foo
=> #user.MyType{:a [1 2 3], :b [4 5 6]}
然后你可以写更复杂的构造函数,使用这个,例如
You can then write more sophisticated constructor functions that use this, e.g.
(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]}
和mutate-and-return也是免费的 - 您只需使用 assoc :
And "mutate-and-return" also comes for free - you can just use assoc:
(assoc foo :b [7 8 9])
=> user.MyType{:a [1 2 3], :b [7 8 9]}
这篇关于Clojure的defrecord - 如何使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!