2011-02-16 51 views
7

显然,你不能叫有记录构造应用:Clojure记录构造函数不是一流的?

(defrecord Foo. [id field]) 

(apply Foo. my-list) 

在读取时失败,因为它没有预料到富。在那个地方。

唯一的解决办法很明显我能想到的是,添加一个工厂函数:

(make-foo [id field] (Foo. id field)) 

可以apply'ed当然。

我错过了什么?我希望这从C#/ Java,但只是认为这是有点令人失望的Clojure ...

+0

同意这是一个有点古怪,但个人因为我发现工厂的功能相当有用它从来就不是一个问题 - 这个模式支持更多的惯用Clojure使用,为您提供更多的预处理参数灵活性,允许不同目的的不同组构造函数,提供一个抽象层等。 – mikera 2011-02-17 01:08:23

回答

10

盘旋回本后的1.3 ....

在Clojure中1.3,defrecord创建两个生成的构造函数。鉴于:

(defrecord Person [first last]) 

这将创建一个位置构造函数->Person

(->Person "alex" "miller") 

和地图构造函数map->Person

(map->Person {:first "string"}) 

因为这是一个地图,所有键都是可选的,在构建的对象中没有价值。

您应该从声明记录的ns中要求/使用这些函数,但不需要像使用Java类构造函数时那样导入记录类。

更多细节:

3

这个问题是已知的,并有很多关于Clojure邮件列表讨论它。未来的Clojure版本可能会增加更多的支持。

现在你必须使用自己的函数或使用https://github.com/david-mcneil/defrecord2支持像一些特点:在eval'able形式

  • 打印
  • 提供Clojure的功能构造
  • 接受命名参数(映射)在构造
  • 参与前/后的步行多方法
6

Foo.是一个Java类构造函数,因此它具有典型的Java互操作约束以及如何调用它。创建构造函数是一种常用的解决方案(这也意味着您不必在不同的名称空间中导入Foo)。

+0

这是一个Java类ctor shou ld是一个实现细节?我认为这是具有更好性能特征的“新”折叠。 – 2011-02-16 14:29:22

+0

我希望它只是一个实现的细节,但这不(如此)的情况。 – 2011-02-16 14:43:32