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

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

+1
ClojureScript
编辑

我试图在变量上设置一些 arglists 元数据。但是当访问元数据时,参数列表不会被保留。

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]])

不确定这是否是由于 ClojureScript 中 "变量" 的独特性质而必要的行为,还是只是一个错误。

编辑
似乎是一个错误。Jira 问题追踪单: https://clojure.atlassian.net/browse/CLJS-3277

1 答案

0

问题的根本在于 CLJS 在运行时没有具体化的变量。元数据实际上是保存在编译器端(在 CLJ 中)的,但似乎有一些合并逻辑不好,这会在输出变量元数据时将其删除。

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

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

与 CLJS 对比

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