Macros 建议使用宏向Clojure';defs记录构造函数?

Macros 建议使用宏向Clojure';defs记录构造函数?,macros,constructor,clojure,record,Macros,Constructor,Clojure,Record,clojure中的defrecord允许使用自定义字段定义简单的数据容器 e、 g 结果的最小构造函数只接受位置参数,没有其他功能,例如字段的默认设置、字段验证等 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} 总是可以编

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

e、 g

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

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}
总是可以编写包装默认构造函数的函数来获得更复杂的构造语义——使用关键字参数、提供默认值等等


这似乎是宏提供扩展语义的理想场景。人们为richer
defrecord
构造编写和/或推荐了哪些宏?

这里有一种方法:

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

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

我们发现重要的是:

  • 能够使用命名(可能是部分)参数构造记录:(newfoo{:a1})
  • 通过复制现有记录并进行修改来构造记录的能力:(new-foo-old-foo{:a 10})
  • 字段验证-如果传递声明的记录字段之外的字段,则抛出错误。当然,这实际上是合法的,而且可能有用,所以有一些方法可以让它成为可选的。因为这在我们的使用中是罕见的,所以更可能是一个错误
  • 默认值-这些值非常有用,但我们尚未实现。Chas Emerick在这里写过关于添加默认值支持的内容:
  • 打印和pprint支持—我们发现,以一种可以返回原始记录的形式打印和pprint记录非常有用。例如,这允许您运行测试、滑动实际输出、验证并将其用作预期输出。或者从调试跟踪中滑动输出并获得真正的可评估表单
使用默认值和不变量定义记录。它创建一个可以使用关键字args来设置字段值的ctor

(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

但它们只有在。

的上下文中才有意义。它们肯定同意可能是错误的未定义字段(但在有意时有用)。人们可能知道扩展字段是故意的,它可能有不同的函数,并且直接assoc抛出错误。我还想知道扩展记录上的元数据是否有用。我应该指出,就如何与Clojure/Java生态系统协同工作而言,defrecord有更多的用途。上面的“简单数据容器”一点也不意味着基本,恰恰相反。应该提到的是,在Clojure 1.3.0中,您可以执行
(map->Book){:作者“J.R.R托尔金”,书名“指环王”,ISBN 9780618517657)
#用户。书籍{:作者“J.R.R托尔金”,书名“指环王”:ISBN 9780618517657}
有关克劳德指出的特征的文档,请参阅:
(new-Foo :a "bad")
; AssertionError