Clojure を学習していくうちに、次の問題にたどり着きました。
setup: addNode [id data] メンバー関数を持つdeftype
、で作成されたグラフ データ構造のクラス。definterface
次のように、直接呼び出されたときに期待どおりに動作します(.addNode graph "anItem" 14)
アイデア:文字列のトークン化とグラフの更新はどちらもかなりの時間を消費するため (少なくとも数百万行)、ファイルを連続して読み取ってトークン化し、トークン リストをエージェントにプッシュして、`(.addNode を実行します。グラフ ID データ) 部分。
問題:エージェントがクラス インスタンスのメンバー関数を更新関数として受け入れるようにする正しい構文が見つからないようです。
簡略化されたコード (ここでは名前空間を削除しました。タイプミスが含まれている可能性があります!):
; from graph.clj
(definterface IGraph
(addNode [id data])
(addNode2 [_ id data]))
(deftype Graph [^:volatile-mutable nodes] ; expects an empty map, else further calls fail horribly
IGraph
(addNode [this id data] (set! nodes (assoc nodes id data)) this)
(addNode2 [this _ id data] (.addNode this id data) this))
; core.clj
(def g (Graph. {}))
(def smith (agent g)) ; agent smith shall do the dirty work
(send smith .addNode "x" 42) ; unable to resolve symbol
(send smith (.addNode @smith) "x" 42) ; IllegalArgumentException (arity?)
(send smith (.addNode2 @smith) "x" 42) ; same as above. Not arity after all?
(send smith #(.addNode @smith) "x" 42) ; ArityException of eval (3)
(send smith (partial #(.addNode @smith)) "x" 42) ; the same
; agent smith, the president is ashamed...
5 行はさまざまな理由で機能しませんが、単純な
(def jones (agent 0))
(send jones + 1)
; agent jones, this nation is in your debt
正常に実行されます。これは可能なはずですが、何が間違っていますか?