Clojure的defrecord - 如何使用它? [英] Clojure's defrecord - how to use it?

查看:185
本文介绍了Clojure的defrecord - 如何使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆