2011-02-03 9 views
12

एक पर्सिस्टेंट्यूयू को एक रेफरी में दिया गया है:एक रेफरी में एक PersistentQueue पॉप करने के लिए बेवकूफ तरीका क्या है?

(def pq (ref clojure.lang.PersistentQueue/EMPTY)) 

कतार को पॉप करने और परिणाम प्राप्त करने का बेवकूफ तरीका क्या है?

आपकी आलोचना के लिए मेरा सबसे अच्छा प्रयास:

(defn qpop [queue-ref] 
    (dosync 
     (let [item (peek @queue-ref)] 
      (alter queue-ref pop) 
      item)) 

बदले में कतार का इन-ट्रांजैक्शन मान देता है जो पहले से ही पॉप किया गया है, इसलिए आप केवल अपने आप में बदलाव नहीं कर सकते हैं।

+0

कतार में जोड़ने के लिए Idiomatic होगा: (dosync (pq conj new-item बदलें) –

उत्तर

5

मैं आपके डॉसिनक के शरीर को सारणित करने के लिए कुछ और मूर्खतापूर्ण लघु नहीं सोच सकता।

हालांकि यदि आप स्टंट के लिए हैं, तो आप ऑफ-बाय-वन हैक: हमेशा पीक्यू के सिर को कचरा के रूप में मानें (इसमें पहले पॉप किए गए आइटम शामिल हैं)। यह इस प्रकार है कि आप qpop पुनर्लेखन कर सकते हैं:

(defn qpop [queue-ref] 
    (peek (alter queue-ref pop)) 

यह शून्य के लिए विशेष जाँच करता है जोड़ने (विशेष रूप से जब आप संयोजक) पड़ता है। इसका मतलब यह है कि आइटम के संदर्भ में इसके लिए लंबे समय तक संदर्भ रखना चाहिए (हालांकि यदि आप पीक्यू के इम्प्ले को देखते हैं तो आप देखेंगे कि यह बहुत से लंबे समय तक पॉप किए गए आइटमों के संदर्भ रख सकता है, इसलिए लवली पहले से ही धुंधली है)।

मैंने इस हैक here का उपयोग किया।

+0

आप एक डरावनी दोस्त हैं। [मेरा मतलब है कि एक तारीफ के रूप में। :)] –

1

आपका डॉसिंक शरीर सामान्य लिस्प के prog1 मैक्रो का उपयोग करके सरलीकृत किया जा सकता है, हालांकि कोर क्लोजर में इसकी कमी है। Clojure में आप इसे एक फ़ंक्शन (मैक्रो के बजाए) कैसे बना सकते हैं, इसके बारे में कुछ चर्चा के साथ एक सरल कार्यान्वयन on the Google group है।

+0

धन्यवाद, अच्छी टिप। –

संबंधित मुद्दे