在此(http://vimeo.com/14709925)视频中编辑运行程序,该程序在循环中呈现opengl
个内容。
当我运行时:
(def a 10)
(defn myloop
[]
(while (= 1 1)
(println a)
(Thread/sleep 1000)))
(myloop)
然后更改a
的值,reval什么都不做,值似乎没有改变。我正在使用LightTable
IDE。我应该切换到emacs
吗?
答案 0 :(得分:3)
一种可能性是重新评估没有发生,因为它是在与正在运行的程序相同的线程上完成的。尝试使用myloop
而不是(future (myloop))
在另一个主题中运行(myloop)
,然后在几次打印后重新def
a
,看看它是否发生了变化。< / p>
请注意(在当前的Clojure版本中)每次遇到时都会取消引用所有vars,从而允许这种动态行为,但重新def
- 除了在交互式测试/实验/演示期间不赞成。请参阅atoms和refs。
vars的这种行为的另一个后果是解除引用会影响性能关键紧密循环的效率。如果不需要动态行为,您可能会看到以下习惯用法首先捕获值(请注意,在识别出瓶颈之前,您不应尝试预先优化)。
(def foo 42)
(let [foo foo] ; capture value of foo within scope of let
(loop ...
; do something with value of foo captured before entering loop
... ))
答案 1 :(得分:2)
我知道这不是你问题的直接答案 - 但如果你想在Clojure中以这种方式改变状态,我认为使用其中一个构造进行状态操作可能更为惯用(例如,原子)而不是重新评估def。
如果您可能需要多个线程,尤其如此,如果您正在处理图形,则可能就是这种情况。
(def a (atom 10))
(defn myloop []
(while (= 1 1)
(println @a)
(Thread/sleep 1000)))
(myloop)
(reset! a 9)