我可以在Clojure记录中创建可变状态吗?

Zub*_*air 9 clojure

我正在考虑使用Clojure记录映射到我的程序中的更改实体.他们是可变的吗?或者你需要在记录中使用额外的参考?我对此有点困惑

mik*_*era 12

非常值得观看Rich Hickey关于身份和状态的精彩视频.

记录被设计为不可变的,并将某些东西的状态存储为值.

为了模拟更改实体的状态,我建议使用引用表示当前状态的不可变值引用.您可以将记录用于不可变状态,但通常只使用简单的映射更简单.

一个简单的例子,其中可变状态是游戏的记分牌:

; set up map of current scores for each player
(def scores 
  (ref 
    {:mary 0 
     :joe  0   }))

; create a function that increments scores as a side effect
(defn add-score [player amount]
  (dosync
    (alter scores update-in [player] + amount)))

; add some scores
(add-score :mary (rand-int 10))
(add-score :joe (rand-int 10))

; read the scores
@scores
=> {:mary 6, :joe 1}
Run Code Online (Sandbox Code Playgroud)

  • alter和update-in都会自动传递他们不理解的任何参数,因此这可以更简洁(并且更可读)写为`(alter scores update-in [player] + amount)`. (2认同)

Art*_*ldt 5

我发现我更常见的是在refs中记录而不是记录中的refs.mikira建议使用简单的地图听起来非常好.

从地图开始,并在必要时切换到不太灵活的东西.