Ich bin sehr neu in Clojure. Könnt ihr mir Erklärungen mit realen Szenarien geben? Ich meine, wo man Ref, Var, Agent, Atom benutzt. Ich las ein Buch, konnte aber die Beispiele der realen Welt immer noch nicht verstehen.
Ich empfehle "The Joy of Clojure" oder "Programming Clojure" für eine echte Antwort auf diese Frage. Ich kann einen kurzen Ausschnitt der Motivationen für jeden reproduzieren:
Sehen Sie sich zunächst dieses Video zum Thema Identität an und / oder studieren Sie hier .
Der koordinierte Zugriff wird verwendet, wenn zwei Identitäten gemeinsam geändert werden müssen. Das klassische Beispiel ist das Verschieben von Geld von einem Bankkonto auf ein anderes. Es muss entweder vollständig oder gar nicht verschoben werden.
Der unkoordinierte Zugriff wird verwendet, wenn nur eine Identität aktualisiert werden muss. Dies ist ein sehr häufiger Fall.
Der synchrone Zugriff wird verwendet, wenn erwartet wird, dass der Anruf wartet, bis sich alle Identitäten erledigt haben, bevor er fortgesetzt wird.
Asynchroner Zugriff ist "Feuer und Vergessen" und lässt die Identität in ihrer eigenen Zeit ihren neuen Zustand erreichen.
state-a
, aber dabei darauf verweise,state-b
brauche ich immer noch eineref
korrekte? Es ändert sich also nicht mehrere Dinge, sondern bezieht sich auf mehrere Dinge, während eines von ihnen geändert wird?ensure
Funktion: clojure.github.io/clojure/clojure.core-api.html#clojure.core/… , um dies explizit und effizienter zu gestalten.Refs beziehen sich auf den Status, der zwischen Threads synchronisiert werden muss. Wenn Sie eine Reihe verschiedener Dinge im Auge behalten müssen und manchmal Vorgänge ausführen müssen, die auf mehrere Dinge gleichzeitig schreiben, verwenden Sie refs. Jedes Mal, wenn Sie mehrere verschiedene Statuselemente haben, ist die Verwendung von Refs keine schlechte Idee.
Atome sind für einen unabhängigen Zustand, der zwischen Threads synchronisiert werden muss. Wenn Sie niemals den Zustand des Atoms und irgendetwas anderes gleichzeitig ändern müssen, ist die Verwendung von at atom sicher (insbesondere wenn das gesamte Programm nur einen Zustand enthält, können Sie ihn in ein Atom einfügen). . Als nicht triviales Beispiel ist die Verwendung eines Atoms wahrscheinlich sicher, wenn Sie versuchen, die Rückgabewerte einer Funktion zwischenzuspeichern (dh zu merken) - der Status ist für alles außerhalb der Funktion unsichtbar, sodass Sie sich keine Sorgen machen müssen über eine Zustandsänderung innerhalb der Funktion, die irgendetwas durcheinander bringt.
Der Hauptpunkt der Agenten ist, dass sie in einem anderen Thread ausgeführt werden. Sie können den Wert des Agenten abrufen und ihn anweisen, eine Funktion auf seinen Wert anzuwenden, wissen jedoch nicht, wann die Funktion ausgeführt wird oder auf welchen Wert die Funktion angewendet wird.
Vars sind für den Fall gedacht, dass Sie etwas pro Thread speichern müssen. Wenn Sie ein Multithread-Programm haben und jeder Thread seinen eigenen privaten Status benötigt, setzen Sie diesen Status in eine Variable.
In Bezug auf Beispiele aus der Praxis können wir Ihnen sagen, was Sie verwenden sollen, wenn Sie ein Beispiel dafür geben, was Sie versuchen.
quelle
Als ich zum ersten Mal über diese Typen las, hatte ich auch Schwierigkeiten zu verstehen, wo ich sie verwenden könnte oder sollte. Hier ist meine einfache englische Antwort:
Verwenden Sie eine Variable, wenn sich die Daten nicht ändern. Dies geschieht immer dann, wenn Sie
def
oder die meisten Funktionen verwenden, die mitdef
like beginnendefn
.Verwenden Sie ein Atom, wenn Sie ein einzelnes Element haben, das sich ändert. Ein Beispiel könnte ein Zähler oder ein Vektor sein, zu dem Sie Elemente hinzufügen möchten.
Verwenden Sie einen Ref, wenn Sie zwei oder mehr Dinge haben, die sich gleichzeitig ändern müssen. Denken Sie an "Datenbanktransaktionen", wenn Sie vertraut sind. Das kanonische Beispiel hierfür ist die Überweisung von Geld von einem Konto auf ein anderes. Jedes Konto kann in einer Referenz gespeichert werden, sodass Änderungen so vorgenommen werden können, dass sie atomar erscheinen.
Verwenden Sie einen Agenten, wenn Sie möchten, dass sich etwas ändert, aber es ist Ihnen egal, wann. Dies kann eine lange Berechnung sein oder etwas in eine Datei oder einen Socket schreiben. Beachten Sie, dass Sie mit letzterem verwenden sollten
send-off
.Hinweis: Ich weiß zu schätzen, dass es in jedem von ihnen noch viel mehr gibt, aber hoffentlich sollte dies Ihnen einen Ausgangspunkt geben.
quelle
Ich schrieb einen Artikel mit einer Zusammenfassung des Unterschieds zwischen ihnen und half bei der Auswahl, wann ich welche verwende.
Share state - bei Verwendung von Vars, Atomen, Agenten und Refs?
Ich hoffe, es wird Menschen helfen, Antworten zu diesem Thema zu suchen.
Einige Abkürzungen aus dem Artikel nach dem Vorschlag von @tunaci:
Vars
Atome
Agenten
Refs
Und Flussdiagramm, wenn Sie welches verwenden:
Bitte schauen Sie sich das Bild auf der Website an, da einige Updates immer möglich sind.
Es ist komplex und ein langes Thema, eine vollständige Antwort ohne Kopie und früheren Artikel zu geben. Bitte verzeihen Sie mir, ich leite Sie auf die Website weiter :)
quelle
Atome, Refs und Agenten - etwas Beleuchtung hier http://blog.jayfields.com/2011/04/clojure-state-management.html
quelle