2011-04-05 4 views
9

Clojureレコードを使用して、プログラム内のエンティティを変更することを検討しています。彼らは変更可能ですか?または、レコード内で追加の参照を使用する必要がありますか?私はこれについてちょっと混乱していますClojureレコード内で可変状態を作成できますか?

答えて

12

それはよく見て価値があるRich Hickey's fantastic video on identity and stateです。

レコードは、不変となるように設計されており、値の状態を格納します。

変化するエンティティの状態をモデル化するには、現在の状態を表す不変値を参照するrefを使用することをお勧めします。不変状態のレコードを使用することもできますが、単純なマップを使用するだけの方が簡単です。

可変状態がゲームのためのスコアボードで簡単な例、:

; 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} 
+2

alterとupdate-inはどちらも理解できない引数を自動的に渡します。したがって、これは '(change score update-in [player] + amount)'としてより簡潔に(より読みやすく)書くことができます。 – amalloy

+0

@amalloy - ありがとう!新しいトリックを学ぶのは良いです:-)更新しました – mikera

5

私は私がはるかに一般的に記録で参照文献より引用文献のレコードを入れて発見しました。 mikiraのアドバイスはシンプルなマップを使うのがとても良いです。

地図から始め、必要なときに柔軟性の低いものに切り替えます。

関連する問題