9

显然,您不能使用记录构造函数调用 apply :

(defrecord Foo. [id field])

(apply Foo. my-list)

在读取时失败,因为它不期望 Foo。在那个地方。

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

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

当然可以应用。

我错过了什么吗?我希望这来自 C#/Java,但只是认为这在 Clojure 中有点令人失望......

4

3 回答 3

11

回到这个post-1.3....

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

(defrecord Person [first last]) 

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

(->Person "alex" "miller")

和地图构造函数map->Person

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

因为这是一个映射,所以所有键都是可选的,并且在构造对象中采用 nil 值。

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

更多细节:

于 2012-01-21T19:13:17.373 回答
6

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

于 2011-02-16T13:51:03.817 回答
3

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

现在你必须使用你自己的函数或使用https://github.com/david-mcneil/defrecord2它支持一些特性,比如:

  • 以可评估的形式打印
  • 提供 clojure 函数作为构造函数
  • 在构造函数中接受命名参数(映射)
  • 参与前/后步行多方法
于 2011-02-16T12:56:05.447 回答