通常,当我在库中看到clojure协议时,协议方法将被包装在一个函数中,通常几乎没有添加功能.例如.: (defprotocol Pfoo (foo-method [this]))(deftype Atype [x y] Pfoo (foo-method [this] (do-something)))(defn foo [
(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上方的协议.
那么为什么协议经常屏蔽功能?协议方法不能成为面向客户的部分,而不是包装功能?
协议是两种具体实体之间的接口点.一个是调用协议的代码(在你的例子中调用foo),另一个是实现它的代码(Atype foo-method).对于另一个人来说,方便是不方便的.实现者希望提供完整的最小接口,而呼叫者希望能够支持最丰富的API.你提到了ClojureScript的核心;看看那里的ISeq协议.它由几种类型实现,每种类型必须实现-first和-rest.为了使这些尽可能容易实现,在其arg上不需要调用seq.然而,相关的功能首先和休息,面对调用者支持传递非序列如字符串,向量等,所以这个通用功能由非协议功能提供.当然,面向来电者的API比接下来,map,filter,sequential destructuring等都建立在-first和-rest之上.
fns提供的其他常见功能包括协议方法包括参数验证(如断言),默认参数和对var-args的支持.