为什么clojure协议方法经常被函数包装?

时间:2013-03-28 04:23:29

标签: clojure protocols clojurescript

通常当我在库中看到clojure协议时,协议方法将被包装在一个函数中,通常几乎没有添加任何功能。 e.g:

(defprotocol Pfoo
    (foo-method [this]))

(deftype Atype [x y]
    Pfoo
    (foo-method [this] (do-something)))

(defn foo [arg] (foo-method arg))

通常希望客户端调用函数foo,而不是协议中的foo方法。 (有关此类事件的具体示例,请参阅clojurescript core顶部的协议。

那么为什么协议经常被屏蔽功能呢?无法将协议方法变成面向客户端的部分,而不是包装函数吗?

1 个答案:

答案 0 :(得分:22)

协议代表两种具体实体之间的接口点。一个是调用协议的代码(在您的示例中调用foo的任何内容),另一个是实现它的代码(Atype foo-method)。方便一个人可能不方便另一个。实现者希望提供最完整的最小接口,而呼叫者需要可支持的最丰富的API。

你提到过ClojureScript核心;看看那里的ISeq协议。它由几种类型实现,每种类型都必须实现-first-rest。为了使这些实现尽可能简单,不需要在其arg上调用seq。但是,面向调用者的相关函数firstrest支持传递非seqs,如字符串,向量等,因此这种常见功能由非协议函数提供。当然调用者 - 面对API比nextmapfilter,顺序解构等更加丰富,所有这些都建立在-first-rest之上。

包装协议方法的fns提供的其他常见功能包括参数验证(如断言),默认参数和对var-args的支持。