【问题标题】:Why isn't my map being updated?为什么我的地图没有更新?
【发布时间】:2016-04-21 12:52:26
【问题描述】:

clojure 很新,所以请善待。

(def state {:currentPosition "1"})

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

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

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

是真的

因此,循环开始,然后在循环内部,我正在更新状态。为什么循环没有结束而只是停止灯台?谢谢

【问题讨论】:

  • Ben,根据您的具体要求,Piotr 的回答是正确的。您可能知道这一点,但您正在做的事情并不惯用。 (有时你无论如何都需要做这种事情,这就是原子存在的原因。)当你第一次学习这门语言时,按照你习惯的方式做事是可以的,但是你会想学习 Clojure-样式编码策略很快。一开始可能有点尴尬,但是一旦你习惯了函数式编程,它就会变得美丽而有趣(恕我直言)。如果我告诉你你已经听说过的事情,请忽略这条评论。
  • 我完全同意,我正在尝试“正常”编程。这对我习惯的方式来说是一个真正的大变化,哈哈

标签: clojure


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 嘿,我无法测试它是否有效,因为当我尝试这样做时: (not= (state :currentPosition) "2") 它说 Atom 不能转换为 IFn 有什么想法吗?再次感谢您
  • 当你想从一个原子中读取一个值时,你需要deref它:(deref currentPosition)。还有一个简写版本:@currentPosition
  • 太棒了!我明白你对 deref 的意思,但我认为我必须取消对象,而不是像这样的 currentPosition:(not= ((deref state) :currentPosition) "2") 你对 @currentPosition 是什么意思
  • 没关系,刚刚搞定! (not= (@state :currentPosition) "2") 非常感谢
  • 在一个地方有2,在另一个地方有"2"
猜你喜欢
  • 2015-11-11
  • 1970-01-01
  • 2014-06-15
  • 1970-01-01
  • 2018-03-21
  • 2011-10-10
  • 2018-03-13
  • 2016-07-18
  • 1970-01-01
相关资源
最近更新 更多