1

コマンドラインコマンドとその引数を解析するためにマルチメソッドを使用しています。

(defmulti run (fn [command args] command))

(defmethod run :default
  [& _]
  ...)

^{:args "[command]"}
(defmethod run "help"
  [_ & [args]]
  "Display command list or help for a given command"
  ...)

^{:args ""}
(defmethod run "version"
  [_ & [args]]
  "Print program's version"
  ...)

(defn -main
  [& args]
  (run (first args)
    (next args)))

特定のメソッドのメタデータにアクセスしようとすると、clojure は以下を返しますnil

(meta ((methods run) "help"))
4

1 に答える 1

6

そのような可能性はありません。最初の理由 (単純な理由) はdefmethod、特定のメソッドのメタデータを設定する機能を提供しないことです (それはdefmulti許可されますが、マルチメソッド全体に対してのみ許可されます)。2 番目の理由は、multimethod は本質的に単一の関数であり、実行の複数の "バリアント" があり、それぞれが渡されたパラメーターに応じて起動することです。大まかに言えば、呼び出し元の観点からは、関数f1f2以下に定義されているものの間に特別な違いはありません。

(defmulti f1 (fn [x] x))

(defmethod f1 :foo [x]
  ...)

(defmethod f1 :bar [x]
  ...)

(defmethod f1 :baz [x]
  ...)

(defn f2 [x]
  (case x
    :foo ...
    :bar ...
    :baz ...))

個人的には、特定の関数がマルチメソッドか通常の関数かによって、実装の詳細に依存することを検討します。また、マルチメソッドの各メソッドを明示的に文書化する必要がある場合は、各メソッドを通常の関数に置き換えることを検討し、マルチメソッドをまったく使用しないでください。

于 2016-09-17T13:53:15.603 に答える