我们在不同命名空间中的记录和协议方面存在一些问题。
我们在命名空间 foo.proto 中有一个协议。
(ns foo.proto)
(defprotocol Proto
(do-stuff [this x y]))
我在命名空间 foo.record 中有一条记录 RecordA:
(ns foo.record
(:require [foo.proto :as proto]))
(defrecord RecordA [bar])
;; RecordA implements the protocol:
(extend-type RecordA
proto/Proto
(do-stuff [this x y] (* x y (:bar this))))
只要我们在 repl 中,它就可以正常工作。现在,如果我们另一方面制作一个 uberjar 并运行我们得到的代码:
没有方法的实现::do-stuff of protocol:#'foo.proto/Proto found for class
另一方面,如果我们像这样在类型声明中实现协议:
(defrecord RecordA [bar]
proto/Proto
(do-stuff [this x y] (* x y (:bar this))))
我们不再收到错误(这需要一些时间才能弄清楚)。此外,如果我们将 Proto 的声明移动到与 RecordA 相同的 ns 中,我们也不会收到错误消息。
我的问题:
在声明中实现和在扩展类型或扩展协议中实现有什么区别?
如果我们将 Record 和 Protocol 声明移到同一个 ns 中,为什么会起作用?
谢谢