gpt4 book ai didi

clojure - 记录构造函数和位置工厂函数之间的区别

转载 作者:行者123 更新时间:2023-12-02 14:41:06 25 4
gpt4 key购买 nike

假设我定义了一个名为 Node 的记录:(defrecord Node [标签属性children])

经过这个定义,根据docstring defrecord 中定义了一个名为 ->Node 的工厂函数,以及另一个工厂函数 map->Node 和一个 Java 类构造函数 节点。.

我想知道位置工厂函数 ->Node 和构造函数 Node. 之间到底有什么区别,除了一方面是 Java 类构造函数/方法,另一方面是 clojure 函数之间的正常差异(通过正常差异,我在想这样的事实:函数首先-Clojure 中的类,而方法则不然)。

最佳答案

(更新:请参阅此答案的末尾,了解有关基本字段类型、构造函数的参数类型与工厂的参数类型的注释。)

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

这记录在私有(private)函数 clojure.core/build-positional-factory 的文档字符串中;在 REPL 中说 (doc clojure.core/build-positional-factory) 来阅读它,或者 (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))))))

关于参数类型的注释:

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

关于clojure - 记录构造函数和位置工厂函数之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17004856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com