2013-08-24 9 views
7

Ich weiß, dass in Java, wenn ich ein Objekt an eine Methode als Argument übergebe, die Methode die Argumentvariable auf dasselbe Objekt zeigen lässt, anstatt ein Duplikat zu machen. Wie wäre es mit Clojure? Zum Beispiel:Wie funktioniert die Argumentübergabe in Clojure?

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

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

Hat Print-from-Leser eine weitere Kopie von rdr im Speicher, wenn rdr in übergeben wird, oder es zeigt auf die gleiche rdr, die bereits erstellt wird, indem sie mit offener Bindung?

Und gibt es eine Möglichkeit zu überprüfen, ob zwei Clojure-Instanzen auf denselben Speicher zeigen?

Sorry über meine schlechten Begriffe wie "Zeige auf" und "Instanzen", ich bin ein Neuling in Clojure und lerne es immer noch. :-)

Antwort

5

Clojure ist wie Java pass-by-value. Ich denke darüber nach, die Referenzen werden nach Wert weitergegeben. Für Clojure funktioniert es nicht so, Schema und Common Lisp verhalten sich genauso.

Sie können testen, ob zwei Verweise auf den gleichen Speicher zeigen mit identical?:

(? Identisch xy)

Prüft, ob zwei Argumente das gleiche Objekt

+0

(identisch?) Sieht ziemlich praktisch aus, jetzt habe ich einen anderen Trick gelernt! :-) –

4

Laut Antwort auf this question on google groups ist es nach Wert übergeben.

Clojure erbt die Argument-Übergabe Semantik von Java. Es ist also pass-by-value, wobei der übergebene Wert eine Objektreferenz ist. Darüber hinaus gibt es Optimierungsmöglichkeiten, die die Weitergabe von primitiven typisierten Werten ermöglichen.

So Funktionen erstellen keine Kopien, wenn Parameter übergeben werden. rdr in Ihrem Code wird die gleiche Instanz sein.

Sinnvoll ist es, dies aufgrund der Java-Interoperabilität zu implementieren - sonst könnte man den Zustand von Java-Objekten mit seiner Methode nicht (einfach) ändern.

Sie können es leicht testen:

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

Ergebnisse in:

testvalue 
nil 

Wenn bar seine eigene Kopie von m erstellt, dann wird die println nicht den Wert innerhalb bar zugewiesen drucken.

+0

Vielen Dank für Ihre Antwort sind auch! :-D –

Verwandte Themen