2013-08-24 12 views
7

So che in Java, se si passa un oggetto a un metodo come argomento, il metodo consentirà alla variabile argomento di puntare allo stesso oggetto anziché fare un duplicato. Che ne dici di Clojure? Per esempio:Come funziona il passaggio di argomenti in Clojure?

(defn print-from-reader [rdr] 
    (print (.read rdr))) 

(...inside some code... 
    (with-open [rdr (Reader file)] 
    (print-from-rader rdr))) 

Vuol stampa da-reader fanno un'altra copia di RDR in memoria quando RDR viene passato, o è che punta alla stessa rdr che è già creato da con-open vincolante?

E c'è un modo per verificare se due istanze di clojure puntano alla stessa memoria?

Mi dispiace per le mie cattive condizioni come "puntare a" e "istanze", sono un novizio in Clojure e continuo a impararlo. :-)

risposta

5

Clojure è un valore pass-by proprio come Java. Penso che i riferimenti siano passati per valore. Non è un tratto per Clojure funzionare così, Scheme e Common Lisp si comportano allo stesso modo.

È possibile verificare se due riferimenti puntano alla stessa memoria con identical?:

(? Identico xy)

test se 2 argomenti sono lo stesso oggetto

+0

(identico?) Sembra abbastanza utile, ora ho imparato un altro trucco! :-) –

4

In base alla risposta allo this question on google groups il valore è inferiore.

Clojure eredita la semantica di passaggio degli argomenti da Java. Quindi è pass-by-value, dove il valore passato è un riferimento a un oggetto. Inoltre, sono disponibili funzioni di ottimizzazione che consentono il superamento di valori tipizzati primitivi.

Quindi le funzioni non eseguono copie quando si superano i parametri. rdr nel codice sarà la stessa istanza.

Ha senso implementarlo in questo modo a causa dell'interoperabilità java, altrimenti non è possibile (facilmente) modificare lo stato degli oggetti java con il suo metodo.

È possibile verificare facilmente:

(import 'java.util.HashMap) 
(def m (new HashMap)) 
(defn foo [m] (defn bar [m] (.put m "testkey" "testvalue")) (bar m) (println (get m "testkey"))) 

(foo m) 

risultati in:

testvalue 
nil 

Se bar creato la propria copia di m, poi la println sarebbe non stampare il valore assegnato all'interno bar.

+0

Grazie per la risposta anche! :-D –

Problemi correlati