2016-04-20 75 views
1

对clojure很新,所以很善良。为什么我的地图不更新?

(def state {:currentPosition "1"}) 

(while (not= (state :currentPosition) "2") ; this is true 
    (assoc state :currentPosition "2") ; 
)  

这会导致无限循环,它不会运行,但我不明白为什么。条件

(not= (state :currentPosition) "2") 

是真的

因此,在循环开始,然后在循环中,我更新的状态。为什么循环没有结束,只是停止了光表?谢谢

+1

本,彼得的答案是正确的给你特别要求。你可能知道这一点,但你所做的事情不是惯用的。 (无论如何你需要做这种事情,这就是为什么原子存在的原因。)当你第一次学习语言时,按习惯的方式去做事情是很好的,但是你会想要学习Clojure-风格的编码策略很快。起初它可能有些尴尬,但一旦你习惯了函数式编程,它就会变得美丽而有趣(imho)。如果我告诉你你已经听过的东西,就忽略这个评论。 – Mars

+0

我完全同意,我试图编程'正常'。这只是一个真正的大变化,我曾经大声笑 – Ben

回答

6

Clojure datastructures是不可改变的,所以(assoc state :currentPosition "2")不会改变分配给state var的对象,而只是返回一个新版本的地图。

如果您想修改变量值,您需要将它们包装在Clojure's refs之一中。例如,你可以使用​​:

(def state (atom {:currentPosition 1})) 

(reset! state {:currentPosition 2})  
@state ;; => {:currentPosition 2} 

(swap! state update :currentPosition inc) 
@state ;; => {:currentPosition 3} 
+0

很酷,谢谢,现在就试试吧 – Ben

+0

嘿我不能测试它是否工作,因为当我尝试做:(not =(state:currentPosition)“2 “)它说Atom不能投向IFn任何想法?再次感谢你 – Ben

+0

当你想从一个原子读取一个值时,你需要'deref'它:'(deref currentPosition)'。还有一个简写版本:'@ currentPosition' –