2015-07-08 12 views
7

Voglio creare un canale di clojure.core.async da un altro che filtra solo messaggi specifici. Pertanto ho trovato una funzione chiamata filtro <.Come creare un canale da un altro con i trasduttori?

=> (def c1 (chan)) 
=> (def c2 (filter< even? c1)) 
=> (put! c1 1) 
=> (put! c1 2) 
=> (<!! c2) 
2 

Ma la funzione ed i suoi amici sono contrassegnati come deprecato:

Sconsigliato - questa funzione saranno rimossi. Utilizzare trasduttore invece

Ci sono alcuni modi per utilizzare i canali con il trasduttore come chan con il parametro xform. Come posso costruire un nuovo canale da uno esistente usando i trasduttori?

risposta

6

Ho fatto qualche ricerca su questo, ha trovato un paio di interessanti articoli (first e second), e poi ha qualcosa di lavoro utilizzando pipeline

(require '[clojure.core.async :as async :refer [chan <!! pipeline put!]]) 
(def c1 (chan)) 
(def c2 (chan)) 

(pipeline 4 c2 (filter even?) c1) 

(put! c1 1) 
(put! c1 2) 
(<!! c2) 
;;=> 2 

Il secondo articolo ho collegato lo rende un po 'più pulito con qualche aiuto funzioni di tutto la funzione gasdotto:

(defn ncpus [] 
    (.availableProcessors (Runtime/getRuntime))) 

(defn parallelism [] 
    (+ (ncpus) 1)) 

(defn add-transducer 
    [in xf] 
    (let [out (chan (buffer 16))] 
    (pipeline (parallelism) out xf in) 
    out)) 

allora si può semplicemente collegare i canali insieme

(def c1 (chan)) 
(def c2 (add-transducer c1 (filter even?)) 

Per completare la risposta, come ti sei trovato è possibile utilizzare il tubo in modo simile:

(defn pipe-trans 
    [ci xf] 
    (let [co (chan 1 xf)] 
    (pipe ci co) 
    co)) 
(def c1 (chan)) 
(def c2 (pipe-trans c1 (filter even?))) 
+0

Ispirato da voi ho creato un metodo facory usando 'pipe'. (defn da-chan [CI xf] (let [co (chan 1 xf)] (tubo CI co) co)) – sschmeck

+0

bello, contento di aver potuto aiutare. –

+1

ho aggiunto una versione del metodo factory per provare a completare la risposta nel caso in cui altri la cercassero. –

Problemi correlati