Clojure 如何将协议函数与同名异数函数结合起来?
我有一个函数Clojure 如何将协议函数与同名异数函数结合起来?,clojure,Clojure,我有一个函数foo,它接受一个参数,该参数的实现取决于参数的类型,因此有一个协议: (defprotocol Foo (foo [x])) 在同一名称空间中,我还想要一个具有相同名称(foo)的函数,该函数接受变量参数,并为每个参数调用单个argfoo。比如: (defn foo [x1 x2 & more] (doseq [x (concat [x1 x2] more)]) (foo x)))) 如何实现它?使用defprotocol您已经声明了函数foo。稍后调用
foo
,它接受一个参数,该参数的实现取决于参数的类型,因此有一个协议:
(defprotocol Foo
(foo [x]))
在同一名称空间中,我还想要一个具有相同名称(foo
)的函数,该函数接受变量参数,并为每个参数调用单个argfoo
。比如:
(defn foo [x1 x2 & more]
(doseq [x (concat [x1 x2] more)])
(foo x))))
如何实现它?使用
defprotocol
您已经声明了函数foo
。稍后调用(defn foo…
会有效地覆盖以前的声明
一种常见的习惯用法是在协议fn前面加上-
(即-foo
)。这基本上是匈牙利符号,表示“这是一个内部协议函数。在这个名称空间中有一个它的包装器。你应该调用它。”这使协议可以扩展,但允许你包装调用
<> P>我在您的案例中考虑的另一个问题是,名称<代码> FoO 是否适合您的包装器。它在多个
Foo
s上运行的事实表明,像dofoos
这样的东西可能更合适。使用deprotocol
您已经声明了函数Foo
。稍后调用(defn foo…
会有效地覆盖以前的声明
一种常见的习惯用法是在协议fn前面加上-
(即-foo
)。这基本上是匈牙利符号,表示“这是一个内部协议函数。在这个名称空间中有一个它的包装器。你应该调用它。”这使协议可以扩展,但允许你包装调用
<> P>我在您的案例中考虑的另一个问题是,名称<代码> FoO 是否适合您的包装器。它在多个
Foo
s上运行的事实表明,像do foos
这样的东西可能更合适。只是补充Tim Pote的答案,让我引用一个:
[…]协议是实现者的契约,而不是调用者的契约。如果您更改了实现者的合同,那么实现者必须更改
[…]对任何对象都有合理默认值的函数。通常,这种功能根本不需要成为实现者合同(即协议)的一部分
这对协议实现者来说是一种解放,因为您可以在公共api fn中设置默认值或添加对多个算术的支持(就像您的例子一样),而不必在具体实现中担心所有这些。仅在Tim Pote的回答中添加一点,让我引用一句: […]协议是实现者的契约,而不是调用者的契约。如果您更改了实现者的合同,那么实现者必须更改 […]对任何对象都有合理默认值的函数。通常,这种功能根本不需要成为实现者合同(即协议)的一部分
这对协议实现者来说是一种解放,因为您可以在公共api fn中设置默认值或添加对多个算术的支持(就像您的例子一样),而不必在具体实现中担心所有这些。Man电子邮件线程太棒了。谢谢你把这个扔进去。哦,是“另一个”斯图尔特。谢谢你的修复:)老兄,这封邮件太棒了。谢谢你把这个扔进去。哦,是“另一个”斯图尔特。感谢修复:)