在其他命名空间中找不到记录类型的Clojure协议实现

Tho*_*lum 6 records protocols clojure

我们在不同命名空间中的记录和协议存在一些问题.

我们在命名空间foo.proto中有一个协议.

(ns foo.proto)

(defprotocol Proto
   (do-stuff [this x y]))
Run Code Online (Sandbox Code Playgroud)

我在命名空间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))))
Run Code Online (Sandbox Code Playgroud)

只要我们在repl中,这样就可以正常工作.现在,如果我们在另一方面制作一个uberjar并运行我们得到的代码:

没有实现方法:: do-stuff of protocol:#'foo.proto/Proto for class

另一方面,如果我们在类型声明中实现协议,如下所示:

(defrecord RecordA [bar]
    proto/Proto
    (do-stuff [this x y] (* x y (:bar this))))
Run Code Online (Sandbox Code Playgroud)

我们不再得到错误(花了一些时间才弄明白).此外,如果我们将Proto的声明移动到与RecordA相同的ns中,我们也不会得到错误.

我的问题:

  1. 在声明中实现以及在extend-type或extend-protocol中有什么区别?

  2. 如果我们将记录和协议声明移动到相同的ns中,为什么它会起作用?

谢谢

noi*_*ith -2

(:import (foo.proto Proto))您需要在命名空间声明中导入协议foo.record