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

Rob*_*lan 14 protocols clojure clojurescript

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

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

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

(defn foo [arg] (foo-method arg))
Run Code Online (Sandbox Code Playgroud)

并且通常期望客户端调用函数foo,而不是协议中的foo方法.(有关此类事情的具体示例,请参阅clojurescript核心顶部的协议.

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

Cho*_*ser 22

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

你提到过ClojureScript核心; 看看ISeq那里的协议.它由几种类型实现,每种类型都必须实现-first-rest.为了使这些变得尽可能容易实现,既不需要在其arg上调用seq.然而,相关的功能firstrest该脸部呼叫者在非seqs像字符串,载体等所以这种通用的功能是由非协议提供支持传递functions.Of当然面向呼叫者-API比具有更丰富next,map,filter,顺序解构等都建立在-first和之上-rest.

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