Ref,Var,Agent,Atom之间的Clojure差异,以及示例

我是Clojure的新手,你能不能给我解释现实场景。 我的意思是,在哪里使用Ref,Var,Agent,Atom。 我读过书,但是,仍然无法理解现实世界的例子。

Mike asked 2019-07-24T18:59:51Z
5个解决方案
157 votes

我强烈推荐“Clojure的喜悦”或“编程Clojure”来真正回答这个问题,我可以重现一下每个动机的简短动态:

首先观看关于身份概念和/或在此学习的视频。

  • 参考文献用于协调同步访问“多个身份”。
  • 原子用于对单个标识的非协调同步访问。
  • 代理用于对单个标识的非协调异步访问。
  • Vars用于具有共享默认值的线程本地隔离标识。

当两个身份需要一起改变时使用协调访问,典型的例子是将钱从一个银行账户转移到另一个银行账户,它需要完全移动或根本不移动。

当只有一个Identity需要更新时,使用不协调的访问,这是一种非常常见的情况。

当呼叫预期等到所有身份都已确定后再继续之前,将使用同步访问。

异步访问是“一劳永逸”,让身份在其自己的时间内达到新的状态。

Arthur Ulfeldt answered 2019-07-24T19:01:05Z
37 votes

Refs用于需要在线程之间同步的状态。 如果你需要跟踪一堆不同的东西,你有时需要做一些写入多个事情的操作,使用refs。 任何时候你有多个不同的状态,使用refs并不是一个坏主意。

原子用于需要在线程之间同步的独立状态。 如果你永远不需要同时改变原子和其他任何东西的状态,那么使用at atom是安全的(特别是,如果在整个程序中只有一个状态,你可以把它放在一个原子中)。 作为一个非常重要的例子,如果你试图缓存一个函数的返回值(即memoize它),使用一个原子可能是安全的 - 状态对函数外部的所有东西都是不可见的,所以你不必担心 关于函数内部的状态变化弄乱了什么。

代理主要的一点是它们在不同的线程中运行。 您可以获取代理的值并告诉它将函数应用于其值,但您不知道该函数何时运行或该函数将应用于什么值。

Vars适用于需要在每个线程上存储内容的情况。 如果你有一个多线程程序,并且每个线程都需要自己的私有状态,那么将该状态放在var中。

就真实世界的例子而言,如果你提供一个你想要做的事情的例子,我们可以告诉你要使用什么。

Retief answered 2019-07-24T19:01:58Z
29 votes

当我第一次阅读这些类型时,我也很难理解我能够或应该使用每一种类型,所以这里是我的简单英语答案:

当数据不会改变时使用var。 每当您使用send-off或大多数以def开头的函数(如defn)时,都会发生这种情况。

如果您有一个更改的项目,请使用原子。 示例可能是您要添加项目的计数器或矢量。

如果您有两件或多件必须同时更改的东西,请使用参考号。 如果您熟悉,请考虑“数据库事务”。 这种规范的例子是将钱从一个账户转移到另一个账户。 每个帐户都可以存储在ref中,以便可以使更改显示为原子。

当您想要更改某些内容但不关心何时更改时,请使用代理。 这可能是一个很长的计算或写入文件或套接字。 请注意,对于后者,您应该使用send-off

注意:我很欣赏这些中的每一个都有很多,但希望这应该给你一个起点。

optevo answered 2019-07-24T19:02:57Z
20 votes

我写了一篇文章,总结了它们之间的区别,并帮助选择何时使用哪一个。

分享状态 - 何时使用变量,原子,代理和参考?

我希望它能帮助人们在该主题中寻找答案。

@tunaci建议后文章的一些捷径:

瓦尔

Vars对于每个线程都是全局的。

创建后不要更改变量。 这在技术上是可行的,但确实如此   坏主意有很多原因。

原子

为每个线程共享对可变状态的访问权限。 发生变化  同步。 其他线程在运行期间更改状态时重试。

不要长时间使用非幂等函数和函数   执行

代理

为每个线程共享对可变状态的访问权限。 发生变化  异步。

参考文献

Refs的工作方式类似于数据库事务。 写和读   在dosync中保护。 您可以在交易中操作许多安全的参考。

和使用哪一个流程图:flowchart

请查看网站上的图片,因为有些更新总是可行的。

没有副本,给出完整答案是一个复杂而漫长的话题; 粘贴文章,所以请原谅我,我将你重定向到网站:)

kabra answered 2019-07-24T19:05:03Z
4 votes

原子,参考和代理 - 这里有些照明[http://blog.jayfields.com/2011/04/clojure-state-management.html]

Gokul answered 2019-07-24T19:05:27Z
translate from https://stackoverflow.com:/questions/9132346/clojure-differences-between-ref-var-agent-atom-with-examples