2012-10-13 2 views
14

Ich würde gerne wissen, warum defmulti & defmethod verwendet werden? Was sind die Vorteile? Und wie benutzt du es? Bitte erläutern Sie, was im Code passiert.Wie und warum wird defmulti und defmethod verwendet? und was sind die Vorteile?

+0

Sind Sie können definieren, was eine Multimethode ist? Wenn nicht, dann werde ich Ihnen gerne erklären – tgoossens

+0

Hier ist eine Frage, die ich einmal gefragt habe: http://cs.stackexchange.com/questions/4660/difference-between-multimethods-and-overloading Ich antwortete meine eigene Frage auch das könnte Ihnen helfen zu verstehen, was eine Multimethode ist – tgoossens

Antwort

25

In „allgemein“ Sie würden es nennen, wenn/sonst auf Steroiden und in „beeindruckt mich“ Stil würden Sie es mit „dynamischer Dispatch“ nennen, „Laufzeit-Polymorphismus“ usw.

Lets sagen, Sie wollen um eine Funktion "Add" zu definieren, die für verschiedene Datentypen funktionieren sollte, wie im Fall von Int, sollte sie die Zahlen hinzufügen, im Falle von Strings sollte sie die Strings enthalten. Jetzt ist es sehr einfach, es zu implementieren, wenn sonst, im Grunde prüfen Sie den Typ der Argumente und wenn sie Integer sind dann fügen Sie sie, wenn sie Zeichenfolgen dann concat sie sonst werfen Ausnahme. Aber das Problem damit ist, dass, wenn Sie Unterstützung für neue Datentyp hinzufügen möchten in Ihrer Add-Funktion müssen Sie ändern die Add-Funktion, die möglicherweise nicht möglich in Fällen, in denen Sie nicht steuern, die Quelle von Add wie der Fall ist es in einer Bibliothek definiert usw. defmulti und defmethod können Sie dieses Problem zu lösen, dh einen neuen Fall zu bestehenden Funktion hinzufügen, ohne seinen Code zu ändern.

(defmulti add (fn [a b] [(type a) (type b)]))

add der Funktionsname ist, ist die anonyme Funktion Ihre if/else, im Grunde wird dies auf Ihre Add Argumente und der Rückgabewert dieser Funktion wird geprüft aufgerufen werden, wenn eine Umsetzung gibt. Jetzt können wir es für Integer implementieren.

(defmethod add [Integer Integer] ([a b] (+ a b)))

[Integer Integer] Art ist Schalter Fall auf dem Rückgabewert der anonymen Funktion, die wir in defmulti definiert und dann der Umsetzung.

Ebenso können wir für Streicher tun

(defmethod add [String String] ([a b] (str a b)))

es mit ganzen Zahlen Aufruf (add (int 1) (int 2))

Nannte es mit Streichern (add "hello" "world")

es mit etwas aufrufen, uns nicht passt, wenn/else dh nicht Implementierung noch für einen Fall wird zu einer Ausnahme führen

+2

Vielen Dank! Dies war sehr hilfreich! – Phil

+0

Danke für die Erklärung! – goncalvesnelson

7

Von dem, was ich nach dem Lesen der Antwort beobachtet haben (und mit dem oben gegebenen Beispiel), zu verstehen, die folgende ist auch hilfreich:

wenn Sie den Befehl ausführen:

(add (int 5) (int 2)) 

Was passiert ist, dass die ‚add defmulti‘ so ausgeführt wird, um eine Liste der Herstellung:

[Integer Integer] 

mit denen aus, sieht es für jeden ‚add defmethod‘, die mit oben aufgeführte Liste dh identifiziert wird:

(add [Integer Integer]) 

Und leitet die Argumente, die es erhalten hat.

Ein anderer Weg, um die Multi-Methoden definieren, um die Übergabe von Argumenten deutlich zu machen, ist:

(defmulti add (fn [a b] [(type a) (type b)])) 
(defmethod add [Integer Integer] [a b] (+ a b)) 
(defmethod add [String String] [a b] (str a b)) 

Dann die Funktion ausgeführt wird:

(add 12 73) 

oder

(add "thank" "you") 
Verwandte Themen