Có một cách đơn giản hơn để viết mã này trong Clojure:Trao đổi Clojure! nguyên tử dequeuing
(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))
cách khác để viết nó sẽ là:
(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))
Đó dường như còn tồi tệ hơn.
Dù sao tôi có một mã số trong đó sử dụng các nguyên tử cho xếp hàng rất nhiều và sử dụng phương pháp cũ đang thực hiện các mã thực sự bối rối, tôi mong chờ có được một cái gì đó như:
(swap! queue (fn [queue] (AtomSwapResult. atom-value return-value))
hoặc một số cơ chế tương tự trong trao đổi! chức năng vì nó có vẻ giống như loại thứ bạn muốn làm thường xuyên (thậm chí không giới hạn trong việc xếp hàng, tôi đã nhấn một số trường hợp sử dụng khác, nơi nó sẽ hữu ích để trả về một giá trị khác, ví dụ như giá trị cũ được đổi chỗ ra ngoài) và nó không phá vỡ nguyên tử/trao đổi! ngữ nghĩa.
Có cách nào để thực hiện việc này trong Clojure không?
lol tôi đã viết CAS một lần đầu tiên tôi gặp phải vấn đề nhưng nghĩ rằng nó là quá dài dòng và không xem xét tách nó trong một chức năng - cảm giác khá ngu ngốc ngay bây giờ :) –
Lưu ý, rằng bạn có thể không thể phân biệt giữa các nils từ hàng đợi và nils từ một hàng đợi rỗng. Việc kiểm tra với 'count' trước' dequeue! 'Không an toàn cho thread. Vì vậy hãy cẩn thận những cạm bẫy. – kotarak
Yup - hãy nhớ rằng một phần quá - nếu có ai quan tâm - giải pháp đầu tiên ở trên có thể được sửa đổi để kiểm tra xem khóa trên có hiện diện không - và đó là tín hiệu hàng đợi trống. –