带有外部绑定符号的 core.async go 块工作但不宏展开

J. *_*huh 2 clojure thread-safety threadpool clojurescript core.async

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

我想它应该可以正常工作。该x是并发线程不变的,不会改变。对可变数据使用atomasx也应该会导致它的atomXD 例如,对象引用当然不起作用或可能会产生问题!

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

;; => 5
;; nil
Run Code Online (Sandbox Code Playgroud)
(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
Run Code Online (Sandbox Code Playgroud)

它似乎有效,但这是一个坏主意吗?为什么?

任何人都可以解释为什么宏扩展不起作用?

ama*_*loy 6

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

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