異なる名前空間のレコードとプロトコルでいくつかの問題が発生しています。
名前空間 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: #'foo.proto/クラスの Proto が見つかりました
一方、次のように型宣言でプロトコルを実装するとします。
(defrecord RecordA [bar]
proto/Proto
(do-stuff [this x y] (* x y (:bar this))))
エラーは発生しなくなりました (把握するのに時間がかかりました)。また、Proto の宣言を RecordA と同じ ns に移動しても、エラーは発生しません。
私の質問:
宣言での実装と、拡張タイプまたは拡張プロトコルでの実装の違いは何ですか?
Record 宣言と Protocol 宣言を同じ ns に移動すると、なぜ機能するのでしょうか?
ありがとう