Clojure在州内的各州内部发布
我很想听听Clojure大师们对管理层级结构状态的建议。 我发现我经常使用{:structures {:like {:this {:with {:many 'levels}} } } }
并且如果我想通过将原子围绕值(atom {:like (atom 'this)} )
,我发现自己认为这一定是错的。 在顶层使用一个原子通常比较好,而在地图中没有任何值?
如果可能的话,不要在数据结构中使用嵌套原子。
主要原因是不变性是你的朋友。 Clojure是一种功能强大的语言,可以在不可变的数据结构上生长。 大多数库都假定不可变的数据结构。 Clojure的STM采用不可变的数据结构来获得最佳的并发性。 不变性使您有机会在任何一个瞬间拍摄整个状态的一致快照。 运行在不可变数据上的纯函数很容易开发和测试。
如果你把原子放在你的数据结构中,那么你失去了所有不变性的优点,并且会使你的代码变得非常复杂 - 如果它包含许多可变组件,就很难推断数据结构。
一些建议的替代方法:
您可以使用assoc-in
, get-in
, update-in
和dissoc-in
函数来处理嵌套结构。
他们非常方便,但我不知道他们是否可以直接处理原子等。 在最坏的情况下,你应该能够将它们嵌套到deref中,例如:
(def m (atom {:like {:this {:nested (atom {:value 5})}}}))
@(get-in @m [:like :this :nested])
; => {:value 5}
(get-in @(get-in @m [:like :this :nested]) [:value])
; => 5
您可以使用->
使其更具可读性:
(-> @m
(get-in [:like :this :nested])
deref
(get-in [:value]))
; => 5
关于嵌套原子/参考/代理等,我认为这取决于你想要达到的目标。 如果只有其中一个位于顶部并且更改同步,那么推理事物肯定更容易。
另一方面,如果你不需要这种同步,你就会浪费时间做这件事,而用嵌套的atoms / refs / agents你会更好。
底线是,我不认为这两种方式都是“正确的方式”,它们都有其用法。
这是Christophe Grand的博客文章,与这种设置的复杂性摔跤:http://clj-me.cgrand.net/2011/10/06/a-world-in-a-ref/
链接地址: http://www.djcxy.com/p/66877.html