(chan)和(chan 1)有什么区别?

时间:2016-01-26 14:01:16

标签: clojure clojurescript

这两种结构有什么区别? Clojure文档提到后者添加缓冲区。但我不清楚这意味着什么。

2 个答案:

答案 0 :(得分:2)

该数字创建一个固定缓冲区,用于保存值,因此当您使用ie >!!时,它将阻止,除非缓冲区中有空间或立即消耗某些东西。

所以(chan)应该等同于(chan 0) - 没有缓冲区(大小为0的缓冲区)

您也可以提供特定缓冲区而不是数字,请参阅“另请参阅”部分中的here

答案 1 :(得分:2)

如果某个频道“附加”到始终采用其值的go块,则只要将值放入频道,它们就会被再次取出。如果是这种情况,那么通道的缓冲区大小无关紧要。

但请考虑不存在这样的提取器的情况:

(def zero-buf-chan (chan))
(defn two-into-zero []
  (go (>! zero-buf-chan :first)
      (println "First into zero completed - NOT SEEN until run zero extractor")
      (>! zero-buf-chan :second)
      (println "Second into zero completed - NOT SEEN until run zero extractor")))
(two-into-zero)

由于zero-buf-chan无法接受输入,因此不会发生任何事情。这里的'go block'将在第一行暂停,等待退出。

如果我们现在给通道大小为1,那么它将有空间接受第一个输入,之后它会暂停:

(def one-buf-chan (chan 1))  
(defn two-into-one []
  (go (>! one-buf-chan :first)
      (println "First into one completed - SEEN")
      (>! one-buf-chan :second)
      (println "Second into one completed - NOT SEEN until run one extractor")))
(two-into-one)

现在我们将看到

  

首先进入一个完成 - SEEN

在控制台中。

现在我们有两个暂停的go块。 one-buf-chan中包含:firstzero-buf-chan为空。

为了完整性,这里有两种可用于提取的方法:

(defn zero-extractor []
  (go (println "Got from zero at first try: " (<! zero-buf-chan))
      (println "Got from zero at second try: " (<! zero-buf-chan))))

(defn one-extractor []
  (go (println "Got from one at first try: " (<! one-buf-chan))
      (println "Got from one at second try: " (<! one-buf-chan))))

如果您运行这些功能,则会看到所有println,并且两个通道都将被清空。请注意,没有数据丢失。缓冲区的大小只决定了早期阻塞的发生方式。此外,值得注意的是,阻止不会阻止您的程序,而是仅阻止阻止程序。