请在Clojure 2024状态调查!分享您的想法。

欢迎!请参阅关于页面了解有关此页面的一些更多信息。

+1
ClojureScript
编辑

我正尝试在变量上设置一些args列表元数据。但是访问元数据时没有保留args列表。

tmp ❯❯❯ clj -A:cljs -m cljs.main -re node -r
ClojureScript 1.10.773
cljs.user=> (def ^{:arglists '[[x]]} thing 3)
#'cljs.user/thing
cljs.user=> (:arglists (meta #'thing))
()

Clojure中会保留这个数据。

tmp ❯❯❯ clj
Clojure 1.10.1
user=> (def ^{:arglists '[[x]]} thing 3)
#'user/thing
user=> (:arglists (meta #'thing))
[[x]]

在cljs中,它也会保留非arglists元数据。

cljs.user=> (def ^{:foo '[[x]]} thing 3)
#'cljs.user/thing
cljs.user=> (:foo (meta #'thing))
(quote [[x]])

wonder,这个是否是因为ClojureScript中"vars"的独特性质而有必要的行为,还是因为一个bug。

编辑
似乎是bug。Jira任务: https://clojure.atlassian.net/browse/CLJS-3277

1答案

0

问题的根源是CLJS在运行时没有实现了的变量。元数据实际上在编译器端(在CLJ)被保留和访问,但似乎有一些不合理的合并逻辑,这会在输出变量元数据时移除它。

我强烈建议不要在CLJS中进行基于"变量"的"元数据"编程,因为会有更多与Clojure不匹配的问题。Var实例每次都会重新创建,并不能像在CLJ中那样操作。

user=> (def ^{:arglists '[[x]]} thing 3)
#'user/thing
user=> (identical? #'thing #'thing)
true

vs CLJS

cljs.user=> (def ^{:arglists '[[x]]} thing 3)
#'cljs.user/thing
cljs.user=> (identical? #'thing #'thing)
false
...