core.async>怎么样!函数验证是否从go块

时间:2018-01-30 17:46:49

标签: clojure core.async

在core.async中,如果在go块之外调用>!函数,则会抛出错误<! used not in (go ...) block。函数如何知道它没有在go块中执行?我需要创建一些非常相似的东西,我需要确保只能从宏内部调用函数。我该怎么做?我查看了core.async源代码,但我无法弄清楚它是如何工作的。

2 个答案:

答案 0 :(得分:3)

以下是<!的源代码:

(defn <!
  "Takes a value from the channel. Must be called inside a (go ...) block. Will
  return nil if closed. Will park if nothing is available."
  [port]
  (assert nil "<! used not in (go ...) block"))

请注意,assert会针对任何falsey值引发异常,因此如果您在<!块之外使用go,则会收到此错误消息。

当您使用go宏时,它会递归遍历它所包含的所有代码表达式, 替换 符号,例如<! 其他代码 ,不会调用上面显示的“错误案例”代码。

答案 1 :(得分:0)

除了Alan Thompson之外,这里的答案是代码(go宏),替换符号,如<!,其他代码不会调用错误案例< / EM>:

[clojure.core.async.impl.ioc-macros :as ioc]命名空间也用于此目的。

   (dispatch/run
     (^:once fn* []
      (let [~@(mapcat (fn [[l sym]] [sym `(^:once fn* [] ~(vary-meta l dissoc :tag))]) crossing-env)
            f# ~(ioc/state-machine `(do ~@body) 1 [crossing-env &env] ioc/async-custom-terminators)
            state# (-> (f#)
                       (ioc/aset-all! ioc/USER-START-IDX c#
                                      ioc/BINDINGS-IDX captured-bindings#))]
        (ioc/run-state-machine-wrapped state#))))