2013-09-24 6 views
6

異なる名前空間のレコードとプロトコルにはいくつかの問題があります。Clojureプロトコル実装が他のネームスペースのレコードタイプに見つかりません

名前空間foo.protoにはプロトコルがあります。これは罰金限り、私たちはREPLであるとして働く

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

(ns foo.proto) 

(defprotocol Proto 
    (do-stuff [this x y])) 

私は名前空間foo.recordのレコードRECORDAを持っています。 otherhandに我々はuberjarを作成し、コードを実行すると今、私たちが得る:

方法のない実装:プロトコルの行い-もの:# 'foo.proto我々がいる場合/プロトクラス

見つかり一方、そのように型宣言でプロトコルを実装:

(defrecord RecordA [bar] 
    proto/Proto 
    (do-stuff [this x y] (* x y (:bar this)))) 

私たちは、もはや(把握するためにいくつかの時間がかかった)エラーを取得していないし。 また、Protoの宣言をRecordAと同じnsに移動すると、エラーは発生しません。

私の質問は:

  1. 宣言でと型を拡張または拡張プロトコルを実装するに違いは何ですか?

  2. レコードとプロトコルの宣言を同じnsに移動すると、なぜ機能しますか?あなたのfoo.record名前空間宣言にプロトコル(:import (foo.proto Proto))をインポートする必要が

おかげ

答えて

-2

+0

いいえ、違いはありません。 –

4

問題は、使用しているファイルにレコードとプロトコルをどのように含めるかに関係している可能性があります。私にとっては、次の作品:

record.clj

(ns testclojure.record 
    (:require [testclojure.proto :as proto])) 

(defrecord RecordA [bar]) 

(extend-type RecordA 
    proto/Proto 
    (do-stuff [this x y] (* x y (:bar this)))) 

proto.clj

(ns testclojure.proto) 

(defprotocol Proto 
    (do-stuff [this x y])) 

core.clj

(ns testclojure.core 
    (:require [testclojure.record :refer [->RecordA]] 
      [testclojure.proto :refer :all]) 
    (:gen-class)) 

(defn -main [& args] 
    (-> (->RecordA 2) 
     (do-stuff 2 6) 
     (println))) 

lein uberjar後と直接jarファイルを実行しているが、私が取得します正解は24です。

なぜ異なる名前空間と拡張の組み合わせで動作するのかについては、defrecordはJavaクラスを作成し、extend-typeはプロトコルの:implsというエントリにエントリを作成します。

私はプロトコルの実装、すなわち、別に定義したレコードへのプロトコルを拡張しようとしている:私は同じ問題のように見えるものに実行しているよ

1

私はレコードとインラインで実装を定義するのではなく、(拡張プロトコル)を使用しています。レコード、プロトコル、実装は同じ名前空間にあります。しかし、私はそれを呼び出そうとすると、実装が存在しないと訴える。私はエクステンダーを見れば

(extend-protocol MyProtocol 
    myns.message.Message 
(my-protocol-function [this] (println "got here"))) 


(my-protocol-function new-msg) 

=> IllegalArgumentException No implementation of method: :my-protocol-function of protocol: #'myns.connector/MyProtocol found for class: myns.message.Message clojure.core/-cache-protocol-fn (core_deftype.clj:544) 

はしかし、私は、私はレコードにプロトコル定義をインライン化した場合しかし、そこ

(extenders MyProtocol) 
=> (myns.message.Message) 

私の記録は、(拡張?)

(extends? MyProtocol myns.message.Message) 
=> false 

偽で見ますすべて期待どおりに動作します。

関連する問題