core.async go block with outside bound symbols 有效但不宏展开

core.async go block with outside bound symbols works but does not macroexpand

过去几周我一直在使用 Clojure 和 Clojurescript 中的“core.async”,想知道在 go 中使用外部绑定符号是否是个好主意,因为有一个线程池,可能其中任何一个都可以使用绑定符号。它可以评估它,但宏扩展不起作用 - 请参阅以下片段

我想它应该可以正常工作。 x 是不可变的,不会被并发线程更改。使用 atom 作为可变数据的 x 也应该有效,因为它是 atom XD 例如对象引用当然不会工作或者可能会产生问题!

(let [x 5]
  (clojure.core.async/go
   (println x)))

;; => 5
;; nil
(clojure.walk/macroexpand-all
   '(let [x 5]
      (clojure.core.async/go
        (println x))))

;; => Syntax error macroexpanding clojure.core.async/go at (your_project.cljc:93:3).
;;    Could not resolve var: x

这似乎可行,但这是个坏主意吗?为什么?

谁能解释为什么宏展开不起作用?

macroexpand-all 不是高保真扩展器。它使用适用于简单宏的基本过程,但它并不能完成实际编译器所做的所有事情。值得注意的是,它不会管理绑定应该引入的 &env 映射。我假设 core.async 需要查看 &env 以确定绑定是本地绑定还是变量。

因此,您不应该期望 macroexpand-all 在这里工作,但是编写此类代码并没有错。