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

What is the difference between (chan) and (chan 1)?

这两种结构有什么区别? Clojure 文档提到后者添加了一个缓冲区。但是我不清楚那是什么意思。

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

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

除了数字之外,您还可以提供特定的缓冲区,请参阅 "see also" 部分中的 here

如果一个通道 'attached' 到一个总是取其值的 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)

所以现在我们将看到

First into one completed - 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))))

如果你运行这些函数那么所有的printlns都会被看到并且两个通道都会被清空。请注意,不会丢失任何数据。缓冲区的大小只决定了早期阻塞的发生时间。此外,请注意阻塞并不是阻塞您的程序,而是仅在 go 块内阻塞。