2017-05-08 95 views
1

从我读的地方看,如果你将一个新值绑定到Clojure中的一个动态变量,那么这个新值只能在该线程中使用。动态变量和线程/睡眠

因此,为了测试,我创建了这个代码:

(def *dynamic-var* "dynamic var") 

(defn run-it [] 
    (future (binding [*dynamic-var* "new-value"] (Thread/sleep 3000) (println *dynamic-var*))) 
    (future (Thread/sleep 1000) (println *dynamic-var*))) 

我的问题是:为何第一个线程(必须打印的“新价值”)从未运行?它从不向控制台输出“新值”。

回答

1

的问题是,你需要标记您的VAR动态与元数据:

(def ^:dynamic *dynamic-var* "dynamic var") 

(defn run-it [] 
    (future (binding [*dynamic-var* "new-value"] (Thread/sleep 3000) (println *dynamic-var*))) 
    (future (Thread/sleep 1000) (println *dynamic-var*))) 

随着^:dynamic补充说,当你运行(run-it)它会打印出:大概

dynamic var 
new-value 

没有了它你看到一条警告信息:

Warning:dynamic-var未声明为动态,因此不能动态重新绑定,但其名称暗示了其他情况。请注明^:dynamic dynamic-var或更改名称。

+0

谢谢,明白了!我正在从静态类型化Java转换为动态类型化Clojure。我习惯于IDE的支持,并且犯这么多错误,因为这个工具并没有警告我。你提到的“警告”实际上并没有出现。谢谢! –

+0

不客气!当我在REPL中运行代码时,我收到了警告,我没有检查它是否在REPL之外运行时是否打印。 –