我试图了解如何在core.async中制作有状态的传感器。 例如,我如何制作一个传感器来计算通道中的元素数量?例如,我想输入要变换为一个取决于它之前的对象数量的计数。
从我读过的方法开始,就是使用volatile!
来保持换能器内的状态,但我仍然不确定如何将所有东西放在一起。
答案 0 :(得分:5)
你需要一个有状态的传感器,在跟踪计数的volatile!
上关闭一个缩小函数。
(defn count-xf [rf]
(let [ctr (volatile! 0)]
(fn
([] (rf))
([result] (rf result))
([result _] ; we ignore the input as
(rf result (vswap! ctr inc)))))) ; we just pass on the count
使用核心功能completing
(defn count-xf [rf]
(let [ctr (volatile! 0)]
(completing
(fn [result _]
(rf result (vswap! ctr inc))))))
电子。 G。使用它如此
(let [ch (chan 1 count-xf)]
(onto-chan ch (repeat 10 true))
(<!! (clojure.core.async/into [] ch)))
;-> [1 2 3 4 5 6 7 8 9 10]
或者,您可以使用map-indexed
换能器,但这可能会帮助您更少地了解换能器的工作原理。此特殊用例还需要额外的每步开销。
(def count-xf (map-indexed (fn [i _] (inc i))))
观察它的implementation与上面的实现差异很小。