2016-04-01 14 views
0

Ich versuche einen Weg zu finden, eine Multi-Methode zu definieren, die (a) auf mehrere Args dispattiert und (b) Methoden erlaubt, die nur auf einige der Argumente achten (der Compiler tut dies) nicht wie die _ in der letzten Methode):defmethod Versand, wenn Varargs involviert

(defmulti whocares (fn [a1 a2] [(class a1)(class a2)])) 

(defmethod whocares [String String] [s1 s2] 
    (println :s2 s1 s2)) 

(defmethod whocares [_ String] [any1 s2] 
    (println :_s any1 s2)) 

Compiler gefällt definitiv nicht das _.

Ich weiß über die: Standard-Catch-All, aber ich brauche etwas feiner (auf einzelne Argumente).

In CL würden wir t als den Typ verwenden, der allem entspricht, aber ich sehe keine Anzeige clojure hat etwas für X, so dass (ia? Was auch immer X) immer wahr zurückgeben würde.

BTW, ich stelle mir vor, es gibt einen Anfang der Java-Klassenhierarchie, aber ich versuche, von meiner Bibliothek zu entfernen, die nur Java-Klassen unterstützt.

Antwort

1

Der einfachste Weg wäre java.lang.Object wie Sie Ihren Fang verwenden alle Art:

(defmulti whocares (fn [a b] [(class a) (class b)])) 

(defmethod whocares [String String] [a b] (println "Two strings" a b)) 

(defmethod whocares [Object String] [a b] (println "Anything and string" a b)) 

(whocares "a" "b") 
;; => "Two strings a b" 

(whocares 1 "c") 
;; => "Anything and string 1 c" 

(whocares :a "c") 
;; => "Anything and string :a c" 

Ich bin nicht sicher, warum Sie die Top-Klasse von Java-Hierarchie nicht verwenden möchten. Es ist möglich, derive mit Ihrem Fang all Dispatch-Wert zu definieren, aber Sie müssen noch die Java Object Klasse ein Kind Ihrer benutzerdefinierten fangen alle Werte machen:

(derive Object :whocares/any) 

(defmulti whocares2 (fn [a b] [(class a) (class b)])) 

(defmethod whocares2 [String String] [a b] (println "Two strings" a b)) 

(defmethod whocares2 [:whocares/any String] [a b] (println "Anything and string" a b)) 

(whocares2 "a" "b") 
;; => "Two strings a b" 

(whocares2 1 "c") 
;; => "Anything and string 1 c" 

(whocares2 :a "c") 
;; => "Anything and string :a c" 
+0

Thx, ich bin ein Idiot. :) Ich habe alles außer Object versucht und angenommen, dass (oops) es keine Integerwerte ergeben würde. – kennytilton