2013-04-12 53 views
3

使用Clojure工作,我们有以下几点:Clojure的协议/功能优先

(defprotocol Greeter (hello [args] "Say hello")) 

(extend-protocol Greeter 
    String 
    (hello [this] (str "Hello " this))) 

(hello "world") ; "Hello world" 

到目前为止,一切都很好。然后,我们添加:

(defn hello [args] (str "Wassup " args "?")) 

这改变了以前的形式输出到:

(hello "world") ; "Wassup world?" 

有没有一种方法,使该协议优先于功能?

回答

5

有没有办法让协议优先于方法?

您无法将defndefprotocol网格化。这是因为defprotocol实际上为当前名称空间中的函数生成绑定。请注意您收到警告,当你在这个命令运行代码:

user=> (defn hello [args] (str "Wassup " args "?")) 
#'user/hello 
user=> (defprotocol Greeter (hello [args] "Say hello")) 
Warning: protocol #'user/Greeter is overwriting function hello 
Greeter 

Protocols documentation解释说,提供一个默认实现正确的方法是使用Object

(defprotocol Greeter (hello [args] "Say hello")) 

(extend-protocol Greeter 
    Object 
    (hello [this] (str "Wassup " this "?"))) 

(extend-protocol Greeter 
    String 
    (hello [this] (str "Hello " this))) 

(hello "world") ; "Hello world" 

(hello 1) ; "Wassup 1?" 
2

协议方法函数,和其他任何var一样,如果你想让它们中的两个具有相同的名字,你必须把它们放在一个单独的命名空间中。