2016-03-21 54 views
2

我有这样的协议命名空间中定义X:在Clojure的另一个命名空间中扩展协议?

(ns x 
    (:require [..])) 

(defrecord MyData [something something-else]) 


(defprotocol MyProtocol 
    (my-fn [data])) 

现在我想创建此协议在另一个命名空间的实现。我试着做这样的事情:

(ns y 
    (:require [..]) 
    (:import (x MyData MyProtocol))) 

(extend-protocol MyProtocol 
    MyData 
    (my-fn [data] 
    ; Do something with the data 
    )) 

然而,当我尝试执行像这样(从我的测试用例):

(ns y-test 
    (:require [x :refer [MyData my-fn]] 
      [...])) 

... 

(let [data (->MyData ...)] 
    (my-fn data)) 

我得到以下异常:

java.lang.IllegalArgumentException: No implementation of method: :my-fn of protocol: #'x/MyProtocol found for class: x.MyData 

如果我将MyProtocol移动到命名空间y它似乎工作。我错过了什么?

更新

ayato_p的回答后,我所需要的协议(在Y),而不是导入,但我仍然得到同样的错误。将extend-protocoly改为x即可解决问题。

回答

1

import仅适用于Java类,因此您不能通过:import导入MyProtocol

以下代码适用于您的记录类型和协议。

(ns y 
    (:require [.. Myprotocol]) 
    (:import (x MyData))) 
+0

我已经试过了,但它仍然给我同样的错误:/ – Johan

+1

啊,我明白了。您还需要在'y-test'命名空间中'require'命名空间'y'。 –