0

タイプヒントを使用して、2 つの単一引数メソッドを区別しようとしています。

たとえば、add-vertex は可変数の引数を取ることができる Java メソッドをラップしているため、ここでは add-vertex が 0、1、または 2 個の引数を取るようにしようとしています...

(defmulti add-vertex (fn [& args] (map class args)))
(defmethod add-vertex [] (add-vertex nil nil))
(defmethod add-vertex Integer [id] (add-vertex id nil))
(defmethod add-vertex Map [props] (add-vertex nil props))
(defmethod add-vertex [Integer Map] [id props]
  ((let [vertex (. *g* addVertex id)]
    (when props
      (apply set-props vertex (interleave (map name (keys props)) (vals props))))
    vertex)))

単一引数関数が 2 つあることに注意してください。それぞれが異なる型をとります (id は Java Integer で、props は Java Map です)。私はClojureが初めてなので、これは完全に間違っていると思います。

4

2 に答える 2

2

これがあなたがやろうとしていることのコードです:

(defmulti add-vertex (fn [& args] (map class args)))
(defmethod add-vertex [] [] (add-vertex nil nil))

;; You could also use java.lang.Integer here, but numbers are Longs by default
(defmethod add-vertex [java.lang.Long] [id] 
                                       (add-vertex id nil))

;; I assume you are using a clojure map ie {:1 2}
(defmethod add-vertex [clojure.lang.PersistentArrayMap] [props] 
                                                        (add-vertex nil props))

(defmethod add-vertex [java.lang.Long clojure.lang.PersistentArrayMap] [id props] ...)

しかし、ご覧のとおり、これはクラスでかなり厄介になります。

別の解決策は、次のようなことを行うことです。

(defn dispatch-fn
  ([] :empty)
  ([a] (cond
         (number? a) :number
         (map? a)    :map
         :else       :error))
  ([a b] (if (and (number? a) (map? b))
             :number-and-map
             :error))
  ([a b & args] :error))

(defmulti add-vertex dispatch-fn)
(defmethod add-vertex :empty [] (add-vertex nil nil))
(defmethod add-vertex :number [id] (add-vertex id nil))
(defmethod add-vertex :map [props] (add-vertex nil props))
(defmethod add-vertex :number-and-map [id props] ...)
(defmethod add-vertex :error [& args] ...)
于 2012-04-19T16:08:36.183 に答える
0

タイプヒンティングを使用していませんが、ディスパッチ関数が評価される値としてクラスリテラルを記述しています。あなたの問題は、ベクター内のすべてのタイプを囲んでいないことです-たとえ1つしかない場合でも。

multimethods について読むことを強くお勧めします。

于 2012-04-17T08:13:57.280 に答える