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

16

我经常在一个库里看到Clojure的协议时,通常会将协议方法包装在一个函数中,通常添加了很少的功能。例如:

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

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

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

通常预期客户端调用函数foo,而不是协议中的foo方法。 (请参见Clojurescript核心顶部的协议,以获得此类事例。)

那么为什么协议通常在函数后面?协议方法不能成为面向客户端的部分,而不是包装函数吗?

1个回答

24

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

你提到了ClojureScript core; 看看那里的ISeq协议。 它由多个类型实现,每个类型都必须实现-first-rest。 为了尽可能地容易实现,这两个方法都不需要在其参数上调用seq。然而,面向调用者的函数firstrest支持传递非序列,如字符串,向量等,因此这个常见功能由非协议函数提供。当然,面向调用者的API甚至比这更丰富,包括nextmapfilter,顺序解构等,在-first-rest上构建。

包装协议方法的函数提供的其他常见特性包括参数验证(如断言),默认参数和对可变参数的支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接