2012-10-13 13 views
14

Mi piacerebbe sapere perché vengono utilizzati defmulti & defmethod? Quali sono i vantaggi? E come si usa? Per favore spiega cosa sta succedendo nel codice.come e perché vengono usati defmulti e defmethod? e quali sono i vantaggi?

+0

Are sei in grado di definire cos'è un multimetodo? In caso contrario, saremo lieti di spiegarti – tgoossens

+0

Ecco una domanda che ho chiesto una volta: http://cs.stackexchange.com/questions/4660/difference-between-multimethods-and-overloading Ho risposto alla mia domanda Inoltre, questo potrebbe aiutarti a capire che cos'è un multimetodo – tgoossens

risposta

25

In "termini generali" si potrebbe chiamare un if/else con gli steroidi e in "mi impressionare" stile che il nome con "spedizione dinamica", "il polimorfismo runtime", ecc

Diciamo che si desidera per definire una funzione "Aggiungi" che dovrebbe funzionare per vari tipi di dati come nel caso di Int che dovrebbe aggiungere i numeri, in caso di stringhe dovrebbe concatenere le stringhe. Ora è molto semplice implementarlo usando if else, in pratica si controlla il tipo di argomenti e se si tratta di numeri interi, quindi aggiungili, se sono stringhe poi concatene loro un'altra. Ma il problema con questo è che nel caso in cui si desidera aggiungere il supporto per il nuovo tipo di dati nella funzione Aggiungi è necessario modificare la funzione Aggiungi, che potrebbe non essere possibile nei casi in cui non si controlla la fonte di Aggiungi come il caso è definito in alcune librerie ecc. defmulti e defmethod consente di risolvere questo problema, ad esempio aggiungendo un nuovo caso alla funzione esistente senza modificarne il codice.

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

aggiuntivo è il nome della funzione, la funzione anonima è la vostra if/else, fondamentalmente questo sarà chiamato sui vostri argomenti aggiuntivi e il valore di ritorno di questa funzione sarà controllato se c'è qualche implementazione. Ora consente di implementarlo per Integer.

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

[Integer Integer] è sorta interruttore caso al valore di ritorno della funzione anonima abbiamo definito in defmulti e quindi l'attuazione.

Allo stesso modo possiamo fare per le stringhe

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

chiamandolo con gli interi (add (int 1) (int 2))

chiamandolo con le stringhe (add "hello" "world")

Calling con qualcosa che non corrisponde nostra se/else vale a dire non ancora l'implementazione per un caso risulterà in un'eccezione

+2

Grazie mille! Questo è stato MOLTO UTILE! – Phil

+0

Grazie per la spiegazione! – goncalvesnelson

7

Da quello che ho osservato dopo aver letto la risposta (e utilizzando l'esempio fornito sopra), il seguente è anche utile per capire:

quando si esegue il comando:

(add (int 5) (int 2)) 

quello che succede è che il 'aggiungono defmulti' viene eseguito così producendo un elenco:

[Integer Integer] 

con quello prodotto, esso cerca qualsiasi 'aggiungere defmethod' che si identifica con la lista di cui sopra e cioè:

(add [Integer Integer]) 

E trasmette gli argomenti che ha ricevuto.

Un altro modo per definire i multi metodi in modo da rendere il passaggio di argomenti chiari è:

(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)) 

quindi eseguire la funzione di:

(add 12 73) 

o

(add "thank" "you") 
Problemi correlati