在Clojure中如何扩展另一个命名空间中定义的协议?

4

我有一个在命名空间x中定义的协议:

(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
    ))

然而,当我尝试像这样执行my-fn时(来自我的测试用例):

(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个回答

2

import 仅适用于 Java 类,因此您无法使用 :import 导入 MyProtocol

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

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

我现在已经尝试了,但它仍然给我相同的错误 :/ - Johan
1
啊,我明白了。你还需要在 y-test 命名空间中 require 命名空间 y - ayato_p

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