Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure core.async中的重叠分区_Clojure_Core.async - Fatal编程技术网

Clojure core.async中的重叠分区

Clojure core.async中的重叠分区,clojure,core.async,Clojure,Core.async,在Clojure中,我可以通过将step参数调优为partition来获得集合的重叠分区: (partition 3 1 (range 20)) ;; ((0 1 2) (1 2 3) (2 3 4) (3 4 5) ...) core.async确实有一个分区函数,但由于它不接受step参数,因此无法获得重叠分区: (let [c (chan)] (go (doseq [n (range 20)] (>! c n))) (go-loop [p (async/

在Clojure中,我可以通过将
step
参数调优为
partition
来获得集合的重叠分区:

(partition 3 1 (range 20))

;; ((0 1 2) (1 2 3) (2 3 4) (3 4 5) ...)
core.async确实有一个分区函数,但由于它不接受step参数,因此无法获得重叠分区:

(let [c (chan)]
  (go (doseq [n (range 20)]
        (>! c n)))

  (go-loop [p (async/partition 3 c)]
    (when-let [v (<! p)]
      (prn v)
      (recur p))))

;;[0 1 2]
;;[3 4 5]
;;[6 7 8]
(让[c(chan)]
(go(doseq[n(范围20)]
(>!cn)))
(go循环[p(异步/分区3C)]
(何时出租(
我意识到这可能意味着能够从一个通道多次读取相同的值。我还意识到,我可以创建自己的函数,从一个通道读取任意多的值,并构建自己的分区

然而,我想知道是否有任何方法可以通过core.async提供的核心API实现这一点


PS.
滑动缓冲区
不起作用,因为我不能一次窥视整个缓冲区。

嗯,我想这个愿望

“能够多次从通道读取相同的值”

与core.async的原则相反

每次从通道读取值时,都是从通道中取出该值

因此,通道行为的好处在于,它保证每个值只读取一次,如果没有值,则不读取(阻塞/停止线程),如果通道关闭,则为零

然后,开始解决问题的下一个问题应该是:为什么(在core.async上)至少有3个不同的函数在通道上输入/输出值。 因此,将通信通道视为一个集合点,在读写器可用之前,存在(core.async)3种不同的应用程序/线程行为:

  • 阻塞线程<代码>>!!正在运行的线程将被阻塞,直到读卡器和写卡器都可用
  • 停止线程(使用go宏块)
    !go块将创建一个伪线程,该线程将被停止,直到读写器都可用。此行为不会阻止正在运行的线程
  • 异步行为
    take!put!
    您只能按照写入和读取的顺序得到保证

实现这一点的一种方法是创建一个函数,从通道读取数据、缓冲值并将其放入新通道。不过,我不确定这有多习惯

例如,每当从输入通道读取所需的
n
项时,下面的函数将
put!
向量放入输出通道,在每次输出后跳过
step

(defn步进分区[在n步中]
(放[出(陈)]
(go循环[缓冲区[]]
(当让[v([1 2 3]
;=> [3 4 5]
;=> [5 6 7]
;=> [7 8 9]

Hmm,可能最好使用异步/分区源的数组复制方法,而不是使用可能会消耗内存的向量?谢谢。这就是我所做的。它不会使core.async变得更容易。我会将你的方法标记为已接受,因为它与我拥有的非常接近。Re:eating memory,
clojure.core/subvec
确实会生成保留原始输入向量的向量,因此内部缓冲区最终将保留放置在通道上的所有值(而放置在
out
通道上的向量将保留到生成时看到的值)。一个简单的解决方法是在每次迭代的
子向量
调用的结果上调用
vec
;结果将是一个在线性时间内构造的新向量。或者,您也可以使用实(非视图)O(对数n)切片。不过,一致认为可能最好只使用数组。