假设我有两个协议: (defprotocol A (f [this]))(defprotocol B (g [x y])) 而且我想将协议B扩展到支持协议A的所有实例: (extend-protocol A String (f [this] (.length this)))(extend-protocol B user.A (g [x y] (* (f x) (
(defprotocol A (f [this])) (defprotocol B (g [x y]))
而且我想将协议B扩展到支持协议A的所有实例:
(extend-protocol A String (f [this] (.length this))) (extend-protocol B user.A (g [x y] (* (f x) (f y))))
主要动机是避免将B扩展到所有可能扩展到A的可能类,或者甚至到其他人可能扩展到A的未知类别(例如,假设A是公共API的一部分) .
但是这不行 – 你得到如下的东西:
(g "abc" "abcd") => #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :g of protocol: #'user/B found for class: java.lang.String>
这是可能的吗如果没有,是否有明智的解决方法来实现同样的目标?
在我看来,你可以用f来实现函数g.如果是这种情况,您需要没有协议B的所有多态.我的意思是以下,因为f是多态的
(defn g [x y] (* (f x) (f y)))
产生支持实现协议A的所有类型的函数g.
通常,当协议位于最底层时,仅根据协议功能(或其他使用协议的其他功能)定义的简单功能使整个命名空间/库/程序非常多态,可扩展和灵活.
序列库是一个很好的例子.简化,有两个多态函数,第一个和其余.序列库的其余部分是普通函数.