0

私がこのマルチメソッドを持っているとしましょう

(defmulti m (fn [v] [(:type v)]))

(defmethod m [Object] [k] (prn "Object"))

(defmethod m [:mykwd] [k] (prn "mykwd"))

のサブクラスで呼び出すとObject、最初の実装に正しくディスパッチされます。

(m {:type String})
"Object"

それで:mykwdそれはまた期待通りに働きます:

(m {:type :mykwd})
"mykwd"

しかし、別のキーワードを指定すると、例外が発生します。

(m {:type :anotherkwd})
#<CompilerException java.lang.IllegalArgumentException: No method in multimethod 'm'
for dispatch value: [:anotherkwd] (NO_SOURCE_FILE:0)>

このディスパッチはどの程度正確に機能しますか?

クラス継承のためにこの動作を維持し、すべてのキーワードをキャッチする「デフォルト」の実装を維持することは可能ですか?

編集この例は単純ですが、バイナリ関数で動作するために必要です。私の本当の必要性は以下の通りです。どうすれば応募できるのかわかりません:default

(defmulti m (fn [arg mp] [(class arg) (:type mp)]))

それから私はそれが何であるかという場合のためにそれを定義する方法を探していargます。これは、の値がクラスの場合に機能しますが、キーワードの場合は機能しません。nil(:type mp):type

(defmethod m [nil Object] [arg mp] (prn "Whatever"))
4

2 に答える 2

5

デフォルトがあります:

(defmethod m :default [x] :oops)

参照:

ページの下部にあるhttp://clojure.org/multimethodsを確認してください。

于 2011-03-23T18:32:22.843 に答える
2

ディスパッチを、がの場合に:typeデフォルト値を返すカスタム関数に置き換えてみてください。についても同じです。次に、キーワードのベクトルをディスパッチできます。継承された動作が必要な場合は、キーワードを階層に追加します。:typenilclass

于 2011-03-23T23:49:19.147 に答える