Die Operationen der transienten Datentypen garantieren nicht, dass sie die gleiche Referenz wie die übergebene zurückgeben. Manchmal entschließt sich die Implementierung, eine neue (aber immer noch vorübergehende) Map nach einer assoc!
zurückzugeben, anstatt die eine zu verwenden Du bist reingegangen.
Die Seite von ClojureDocs in assoc!
hat eine schönes Beispiel , das dieses Verhalten erklärt:
Ich möchte diesen letzten Teil wiederholen, weil er sehr wichtig ist: Die ursprüngliche Sammlung, die Sie übergeben haben, sollte als nicht definierter Wert behandelt werden. Nur der Rückgabewert ist vorhersehbar.
Hier ist eine modifizierte Version Ihres Codes, die wie erwartet funktioniert:
%Vor% Als Nebenbemerkung ist der Grund dafür, dass Sie immer 8 erhalten, weil Clojure gerne eine clojure.lang.PersistentArrayMap
(eine Karte, die von einem Array unterstützt wird) für Karten mit 8 oder weniger Elementen verwendet. Sobald Sie über 8 hinaus sind, wechselt es zu clojure.lang.PersistentHashMap
.
Sobald Sie 8 Einträge überschritten haben, wechselt Ihre Übergangsmatrix die Hintergrunddatenstruktur von einem Array von Paaren ( PersistentArrayMap
) zu einer Hashtabelle ( PersistentHashMap
). Zu diesem Zeitpunkt gibt assoc!
eine neue Referenz statt nur zurück Aktualisierung der alten.
Die einfachste Erklärung stammt aus der Clojure-Dokumentation selbst (Hervorhebung von mir):
Transienten unterstützen eine parallele Menge von 'ändernden' Operationen, mit ähnlichen Namen gefolgt von! - assozi !, conj! usw. Diese machen die gleichen Dinge wie ihre hartnäckigen Gegenstücke, außer dass die Rückgabewerte selbst vorübergehend sind. Beachten Sie insbesondere, dass Transienten nicht direkt angeschlagen werden. Sie müssen den Rückgabewert beim nächsten Aufruf erfassen und verwenden.
Tags und Links clojure vector dictionary collections transient