core.async 频道作为一个原子

core.async channel as an atom

我正在构建一个使用一个文件并生成另一个文件的应用程序。它的作用并不重要,但我想使用 core.async;主要原因是我想学习它,但也希望能够在多核机器上使这个处理速度更快。

我希望该应用程序有 2 种操作模式:您可以从命令行 运行 它,并在 STDIN 上传递一个文件,或者您可以启动一个 REPL 会话,并在那里创建您的输入.我已经在我的 Emacs REPL 中使用了这种方法,我希望能够在命令行 REPL 会话中使用。

当 运行 使用 STDIN 上的文件时,我的代码创建一个通道,创建使用者,并将行放入通道。当我进行交互时,我想我会创建一个通道并将其绑定到一个原子;然后将有一个 API 公开来将单个消息或整个序列添加到频道,这无关紧要。

让我怀疑这个决定的是 examples/articles 没有谈论通道+原子组合。好像这不是一个好的模式。 任何人都可以提供他们的意见吗?也许我只是想得太多=) 对文字墙感到抱歉!

我看不出将可变对象放入原子中有什么好处。原子的目的是充当不可变对象的可变容器。

我猜您想推迟初始化通道,并在决定需要通道时 reset!ing atom。虽然这可行,但我认为这是对原子的滥用。

我建议只使用 delay:

(def ch (delay (chan)))

; The chan is initialized here the first time it's dereferenced
@ch

; And the same cached chan is used here
@ch

这使您无需使用 nil 初始化原子,然后在使用原子之前不断检查原子是否已添加通道。

更好的方法是在 REPL 中简单地评估 (def c (chan))。然后你可以 pass/inspect c 根据需要,但不能改变你的程序的结构。

在 .clj 文件的末尾找到注释表单并不少见,其中包含旨在在 REPL 中评估的助手。例如:

(comment
  (def c (chan))
  (do-something-with-c c))