请考虑以下代码段:
(require '[clojure.core.async :refer :all])
(def my-chan (chan (buffer 10)))
(go (while true
(>! my-chan (rand))))
这基本上提供了一个缓冲通道,它总是包含大约10个随机数。消耗通道后,缓冲区将再次填充。
core.async中是否有这样的抽象?由于存在用于操纵通道消耗的换能器,因此也可能存在用于生产它们的东西:
对于序列,人们会选择这样的东西:
(def my-seq
(map (fn [_] (rand)) (range)))
或者,只是:
(def my-seq (repeatedly rand))
当然没有缓冲,但它可能会让我知道我在寻找什么。
答案 0 :(得分:0)
传感器不会操纵频道消费 - 它们会影响价值,但它们不会影响频道数据的消费。
您似乎想要一种方法来抽象通道的创建,然后将其作为序列从中获取值。这里有一些想法,虽然我不相信core.async在这种情况下确实提供了高于普通clojure.core功能的任何东西。
抽象是按照通常的方式完成的 - 使用函数。这将调用f
并将其结果放在频道上。这里的含义当然是f
会产生副作用,而且不纯,否则从每个价值相同的角度来看,这将是一个非常无聊的渠道。
(defn chan-factory
[f buf]
(let [c (chan buf)]
(go-loop []
(>! c (f))
(recur))
c))
如果你想从中创建一个懒惰的序列,你可以这样做:
(defn chan-to-seq [c]
(lazy-seq
(cons (<!! c) (chan-to-seq c))))
定义你的seq:
(def rand-from-chan (chan-to-seq (chan-factory rand 10)))
(take 5 rand-from-chan)
=>
(0.6873518531956767
0.6940302424998631
0.07293052906941855
0.7264083273536271
0.4670275072317531)
但是,您可以通过以下方式完成同样的事情:
(def rand-nums (repeatedly rand))
所以,虽然您正在做的是一个伟大的思想实验,但找到一些具体的用例可能会更有帮助,然后您可能会收到更具体的想法。祝你好运!