【问题标题】:How does the core.async >! function verify if its being called from inside of a go blockcore.async 怎么样 >!函数验证它是否是从 go 块内部调用的
【发布时间】:2018-07-09 16:45:39
【问题描述】:

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

【问题讨论】:

    标签: clojure core.async


    【解决方案1】:

    这里是<!的源代码:

    (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 将针对任何虚假值抛出异常,因此如果您在 go 块之外使用 &lt;!,则会收到此错误消息。

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

    【讨论】:

    • 甜蜜。谢谢。我将尝试构建类似的东西。
    【解决方案2】:

    除了 Alan Thompson 的答案之外,还有代码(go 宏)用不调用 错误案例的其他代码替换 &lt;! 之类的符号

    还有用于此目的的 [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#))))
    

    【讨论】:

      猜你喜欢
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      相关资源
      最近更新 更多