Denken Sie daran, dass Verzögerungen memoisiert sind, so dass aufeinanderfolgende Aufrufe Ihrer Adressenverzögerung immer die gleiche Adresse wie bei der ersten Verspätung der Verzögerung liefern.
(defn addresses [person-id]
{:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."})
(defn person [id]
(merge {:addresses (delay (addresses id))} {:name "john"}))
(let [person1 (person 1)]
(println @(:addresses person1))
(println @(:addresses person1)))
wird dieser Druck:
{:home 65 Cool St., :work 1243 Boring St.}
{:home 65 Cool St., :work 1243 Boring St.}
Beachten Sie, wie die Heimadresse auf dem zweiten deref der Verzögerung unverändert ist.
Wenn Sie dieses Verhalten nicht möchten, müssen Sie stattdessen eine Funktion schließen.
(defn addresses [person-id]
{:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."})
(defn person [id]
(merge {:addresses (fn [] (addresses id))} {:name "john"}))
(let [person1 (person 1)]
(println ((:addresses person1)))
(println ((:addresses person1))))
wird dieser Druck:
{:home 16 Cool St., :work 1243 Boring St.}
{:home 31 Cool St., :work 1243 Boring St.}
Beachten Sie, wie die Heimat-Adresse auf dem Unter sequent Aufruf zur Schließung anders war.
Also, wenn Sie addresses
Funktion Nebeneffekt ist, sagt Adressen aus einer Datenbank holt. Und die Personen können ihre Adressen ändern, und Sie möchten, dass Ihr Code immer die aktuellste Adresse hat. Das ist etwas, das Sie im Auge behalten sollten, wenn Delay für Sie arbeitet oder wenn eine Funktionsschließung ein besserer Kandidat wäre.
Vielen Dank. Ich fragte mich, ob dies transparent gemacht werden könnte, so dass es zum ersten Mal ausgewertet werden könnte, wenn es verwendet wird. Anstatt die Auswertung manuell zu erzwingen? – Surya
Ich glaube nicht. Clojure ist eindeutig in Faulheit und Kraft, soweit ich weiß. –
Meine Lazymap [Bibliothek] (http://bitbucket.org/kotarak/lazymap) macht genau das. Es bietet transparente Drop-Ins für alle Kartentypen, die ihre Werte nur dann berechnen, wenn sie wirklich abgerufen werden. – kotarak