为什么 Clojure 1.3 说当我将变量声明为动态时变量未声明为动态?
我正在将工作 Clojure 代码(在 Leiningen 项目中)从 1.2 移植到 1.3,但遇到了问题。除了代码本身不再工作之外,我还收到了数十条警告消息,如下所示:
Warning: *tooltip-width* not declared dynamic and thus is not dynamically rebindable,
but its name suggests otherwise. Please either indicate ^:dynamic *tooltip-width*
or change the name.
尽管我已经对用于维护状态的变量进行了看起来正确的修改,但这种情况仍在发生。例如,对于上面的错误,代码已经包含以下内容:
(def ^:dyanamic *tooltip-width* (* 1.8 *slip-width*))
我在两个地方收到这些错误:首先,从命令行,作为执行 lein swank 的结果;其次,在使用 Cc Cw
编译我的 core.clj
文件后,从 Emacs REPL 进行。
为了绝对完整,这是我的 project.clj
文件:
(defproject infwb "1.0.0-SNAPSHOT"
:description "an evolving, experimental workspace for manipulating infocards"
:main infwb.core
:dependencies [[org.clojure/clojure "1.3"]
[seesaw "1.2.1"]
[org.clojars.gw666/sxqj "beta2"]
[org.clojars.gw666/piccolo2dcore "1.3"]
[org.clojars.gw666/piccolo2dextras "1.3"]
[com.miglayout/miglayout "3.7.4"]
]
:dev-dependencies [[swank-clojure "1.3.2"]
[org.clojars.weavejester/autodoc "0.9.0"]]
:autodoc {:name "Infocard Workbench (InfWb)",
:web-src-dir "https://github.com/gw666/infwb/blob"})
除了让我的代码正常工作之外,我还想了解为什么会出现这些错误以及原因我在两个地方都得到了它们。感谢您的帮助。
I'm porting working Clojure code (in a Leiningen project) from 1.2 to 1.3 and having problems. In addition to the code itself no longer working, I'm getting dozens of warning messages like this one:
Warning: *tooltip-width* not declared dynamic and thus is not dynamically rebindable,
but its name suggests otherwise. Please either indicate ^:dynamic *tooltip-width*
or change the name.
This is happening even though I have already made what look like the correct modifications to vars that I'm using to maintain state. For the error above, for example, the code already includes this:
(def ^:dyanamic *tooltip-width* (* 1.8 *slip-width*))
I get these errors in two places: first, from the command line, as a result of executing lein swank
; and second, from the Emacs REPL, after compiling my core.clj
file using C-c C-w
.
To be absolutely complete, here is my project.clj
file:
(defproject infwb "1.0.0-SNAPSHOT"
:description "an evolving, experimental workspace for manipulating infocards"
:main infwb.core
:dependencies [[org.clojure/clojure "1.3"]
[seesaw "1.2.1"]
[org.clojars.gw666/sxqj "beta2"]
[org.clojars.gw666/piccolo2dcore "1.3"]
[org.clojars.gw666/piccolo2dextras "1.3"]
[com.miglayout/miglayout "3.7.4"]
]
:dev-dependencies [[swank-clojure "1.3.2"]
[org.clojars.weavejester/autodoc "0.9.0"]]
:autodoc {:name "Infocard Workbench (InfWb)",
:web-src-dir "https://github.com/gw666/infwb/blob"})
In addition to getting my code working, I'd like to understand why I'm getting these errors and why I'm getting them in both places. Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个简单的错字。
应该是:
发生在我们所有人身上!
It's a simple typo.
should be:
Happens to us all!
您可能需要考虑使用引用或原子而不是变量来维护状态。
引用 Clojure 文档:
(强调我的。)
可以使用
binding
宏将变量设置为新值(对于当前线程)。在 Clojure 1.2 之前,任何 var 都可以像这样反弹,但从 Clojure 1.3 开始,需要将 var 显式声明为^:dynamic
才能允许这样做。 (据我所知,原因是在没有重新绑定的常见情况下,var 查找的速度大大加快。)给出旨在作为反弹名称的 var 是一个常见的约定(但仅此而已)这个:
*foobar*
。由于这种约定,当编译器看到这样命名但未声明为动态的 var 时,它会向您发出警告。总结一下:
atom
、ref
(如果您需要事务)或代理
(用于异步更改)。You might want to consider using refs or atoms instead of vars to maintain state.
To quote the Clojure documentation:
(Emphasis mine.)
Vars can be set to a new value (for the current thread) with the
binding
macro. Up to Clojure 1.2 any var could be rebound like this, but since Clojure 1.3 vars need to be explicitly declared as^:dynamic
to allow this. (As far as I know, the reason is a drastic speed-up of var look-ups for the common case of no rebinding.)It is a common convention (but nothing more) to give vars that are intended to be rebound names like this:
*foobar*
. Because of this convention, the compiler gives you a warning when it sees a var named like this that is not declared dynamic.To sum up:
atom
,ref
(if you need transactions) oragent
(for asynchronous change).