Record构造函数和位置工厂函数之间的区别

jjp*_*jpe 4 clojure

假设我定义了一个名为Node的记录:(defrecord Node [tag attributes children]).

这个定义之后,根据文档字符串defrecord称为工厂函数->Node的定义,以及另一家工厂的功能map->Node和Java类的构造函数Node..

我想知道究竟有什么区别的位置工厂之间的功能->Node和构造Node.,除了正常的分歧,一方面一个Java类构造函数/方法和另外一个Clojure的函数之间(通过正常的差异,我想的东西就像在Clojure中函数是一流的而事实上的方法不是这样的事实.

Mic*_*zyk 8

(更新:请参阅本答案的结尾,以获取有关原始字段类型与ctor参数类型与工厂参数类型的参数类型的说明.)

位置工厂只是直接调用构造函数.除此之外唯一有趣的事情是对于具有大量字段的记录/类型(即超过20,这是Clojure函数可以接受的位置参数的最大数量)使得构造函数调用稍微复杂一些(因为你必须解压缩)来自rest-args seq的一些论点); 正确排放defrecorddeftype处理的位置工厂,并检查是否提供了正确的参数数量,如果没有则抛出适当的异常.

这在私有函数的docstring中有记录clojure.core/build-positional-factory; (doc clojure.core/build-positional-factory)在REPL上说要阅读它,或者(source clojure.core/build-positional-factory)看看来源.

最终结果大致如下:

;; positional factory for a type with up to 20 fields
(defn ->Foo
  "Construct a Foo."
  [x y z]
  (new Foo x y z))

;; positional factory for a type with many fields
(defn ->Bar
  "Construct a Bar."
  [a b c d e f g h i j k l m n o p q r s t & overage]
  (if (= (count overage) 2)
    (new Bar a b c d e f g h i j k l m n o p q r s t
             (nth overage 0) (nth overage 1))
    (throw
     (clojure.lang.ArityException.
      (+ 20 (count overage)) (name '->Bar))))))
Run Code Online (Sandbox Code Playgroud)

关于参数类型的说明:

不确定这是否属于"正常差异"的标题,因此我将明确提及:deftype/ defrecord引入的类可能具有基本类型的字段,在这种情况下,构造函数的相应参数也将是基本类型.但是,从Clojure 1.5.1开始,位置工厂总是采用所有Object参数,即使技术上它们可以被声明为原始接受函数(也就是说,如果涉及的基元类型是long和/或double最多有四个位置参数).