为什么"断言失败:>!不用于(去...)块"

Bob*_*har 3 clojure core.async

我试图找出core.async我REPL和我为我有多么的使用(去环......)不管理资格作为一个"去块"为异步的目的/>完全糊涂了!

我的循环就像......

(async/go-loop [page (range 3)]
  (if (empty? page)
    (async/close! ch)
    (dorun (map (fn [row]
                  (println row)
                  (async/>! ch row)) page)))
  (recur (range (dec (count page)))))
Run Code Online (Sandbox Code Playgroud)

但是REPL都很不高兴......

=>
#object[clojure.core.async.impl.channels.ManyToManyChannel
        0x23465937
        "clojure.core.async.impl.channels.ManyToManyChannel@23465937"]
0
Exception in thread "async-dispatch-12" java.lang.AssertionError: Assert failed: >! used not in (go ...) block
nil
...
Run Code Online (Sandbox Code Playgroud)

为什么(go-loop ...)这个(async/>! row)电话的范围不够?

我是否应该在这里使用循环?

Car*_*ate 7

>!和其他停车呼叫不能在嵌套在go不幸的内部的功能内使用.

go将您提供的代码转换为状态机并查找停车呼叫.但是它不会查看嵌套函数.

来自Clojure.Asyncs Github最佳实践页面:

go块中不受支持的构造和其他限制

go宏停止在函数创建边界处进行转换.这意味着以下代码将无法编译,或者可能只是抛出一个运行时错误,指出<!在go块之外使用:

(go (let [my-fn (fn [] (<! c))]
    (my-fn)))
Run Code Online (Sandbox Code Playgroud)

这是一件值得记住的事情,因为许多Clojure构造在宏内创建函数.以下是无法按预期工作的代码示例:

(go (map <! some-chan))
(go (for [x xs]
      (<! x)))
Run Code Online (Sandbox Code Playgroud)