推荐的宏为Clojure的defrecord构造函数添加功能?

时间:2010-10-04 15:32:18

标签: macros constructor clojure record

clojure中的

defrecord允许使用自定义字段定义简单数据容器。

e.g。

user=> (defrecord Book [author title ISBN])
user.Book

结果的最小构造函数只接受位置参数而没有其他功能,例如字段默认,字段验证等。

user=> (Book. "J.R.R Tolkien" "The Lord of the Rings" 9780618517657)
#:user.Book{:author "J.R.R Tolkien", :title "The Lord of the Rings", :ISBN 9780618517657}

总是可以编写包装默认构造函数的函数来获得更复杂的构造语义 - 使用关键字参数,提供默认值等等。

这似乎是宏提供扩展语义的理想方案。人们为更丰富的defrecord构建编写和/或推荐了哪些宏?

3 个答案:

答案 0 :(得分:9)

支持完整和部分记录构造函数以及支持可评估打印和pprint表单的示例:

David是我的同事,我们正在我们的项目中广泛使用这个defrecord2。我认为这样的事情应该是Clojure核心的一部分(当然,细节可能会有很大不同)。

我们发现重要的事情是:

  • 能够使用命名(可能是部分)参数构建记录:(new-foo {:a 1})
  • 通过复制现有记录并进行修改来构建记录的能力:(new-foo old-foo {:a 10})
  • 字段验证 - 如果您在声明的记录字段之外传递字段,则抛出错误。当然,这实际上是合法的并且可能有用,因此有一些方法可以使它成为可选的。由于它在我们的使用中很少见,因此更有可能是错误。
  • 默认值 - 这些非常有用但我们还没有实现它。 Chas Emerick撰写了关于在此处添加对默认值的支持的文章:http://cemerick.com/2010/08/02/defrecord-slot-defaults/
  • 打印和pprint支持 - 我们发现将记录打印和打印以可以回复到原始记录的形式非常有用。例如,这允许您运行测试,滑动实际输出,验证它,并将其用作预期输出。或者从调试跟踪中滑动输出并获得真正的可评估表单。

答案 1 :(得分:4)

Here is one定义具有默认值和不变量的记录。它创建了一个ctor,可以使用关键字args来设置字段的值。

(defconstrainedrecord Foo [a 1 b 2]
  [(every? number? [a b])])

(new-Foo)
;=> #user.Foo{:a 1, :b 2}

(new-Foo :a 42)
; #user.Foo{:a 42, :b 2}

就像我说的那样......不变量:

(new-Foo :a "bad")
; AssertionError

但它们只在Trammel的背景下才有意义。

答案 2 :(得分:2)