Czy istnieje prostszy sposób, aby napisać ten kod w Clojure:Zamień się na Clojure! atom zdejmującą z kolejki
(def queue (atom {:top nil :queue PersistentQueue/EMPTY}))
(swap! queue #(hash-map :top nil :queue (conj (:queue %) "foo")))
(let [{:keys [top]} (swap! queue
#(hash-map
:top (peek (:queue %))
:queue (pop (:queue %))))]
(println top))
alternatywny sposób byłoby napisać:
(def queue (atom PersistentQueue/EMPTY))
(swap! queue conj "foo")
(let [top (atom nil)]
(swap! queue
(fn [queue]
(reset! top (peek queue))
(pop queue)))
(println @top))
To wydaje się jeszcze gorsza.
Zresztą mam kod, który używa węgla do kolejkowania dużo i za pomocą byłego podejście czyni kod naprawdę mylące, będę oczekiwać tam być coś takiego:
(swap! queue (fn [queue] (AtomSwapResult. atom-value return-value))
lub jakiegoś podobnego mechanizmu w zamiana! działa, ponieważ wydaje się, że coś, co chciałbyś robić często (nie ograniczając się nawet do kolejkowania, trafiłem na kilka innych przypadków użycia, w których warto zwrócić inną wartość, np. stara wartość została zamieniona out) i nie łamie atom/swap! semantyka.
Czy istnieje sposób, aby to zrobić w Clojure?
lol pisałem CAS raz pierwszy natknąłem się na problem, ale myślałem, że to zbyt rozwlekły i nie rozważyć oddzielenie go w funkcji - uczucie całkiem głupi teraz :) –
Zauważ, że prawdopodobnie nie możesz odróżnić nils od kolejki od nils z pustej kolejki. Sprawdzanie z 'count' przed' dequeue! 'Nie jest wątkowo bezpieczne. Tak więc strzeż się pułapek. – kotarak
Yup - pamiętaj, że również część - jeśli ktoś ma na to ochotę - pierwsze rozwiązanie powyżej można zmodyfikować, aby sprawdzić, czy klucz górny jest obecny - i to jest pusty sygnał kolejki. –