我很好奇所以我检查了交换的源代码!在clojure存储库上运行,就像这样:
(defn swap!
"Atomically swaps the value of atom to be:
(apply f current-value-of-atom args). Note that f may be called
multiple times, and thus should be free of side effects. Returns
the value that was swapped in."
{:added "1.0"
:static true}
([^clojure.lang.Atom atom f] (.swap atom f))
([^clojure.lang.Atom atom f x] (.swap atom f x))
([^clojure.lang.Atom atom f x y] (.swap atom f x y))
([^clojure.lang.Atom atom f x y & args] (.swap atom f x y args)))
我不知道“ .swap ”功能在做什么?我试图搜索它,但它没有在同一个文件中定义,所以无法找到它的定义。或者这是另一个特别的东西,实际上根本不是一个功能?
答案 0 :(得分:6)
Clojure 中的很多东西实际上是在 Java 中实现的,比如引用类型(atom,ref,var,agent),数据结构(map,vector,list) ,set),名称空间(实际的Namespace
类)和其他东西。在clojure.core
中阅读 Clojure 函数的源代码时,找到对 Java 方法的互操作并不罕见。
我的理解是,在 Clojure 中实现这些内容有一个长期目标(搜索here以获取 Clojure-in-Clojure ),但是现在这些东西都是在Java
中实现的,这真的不是很糟糕,因为整个语言都是开源的,你可以在github repo中在线检查任何实现细节(已在评论中链接):{{3} (请注意,有一个jvm
和一个clj
文件夹,用于指示内部代码的实现语言。
答案 1 :(得分:5)
在Clojure中,表达式(.x object a b c)
导致方法调用,在Java中将其表示为object.x(a, b, c)
。有关详细信息,请参阅Java Interop。
在这种特殊情况下,swap!
函数调用作为第一个参数传递的clojure.lang.Atom
实例的适当重载swap
方法。 swap
方法包含执行交换的实际逻辑。
答案 2 :(得分:0)
简单地说,原子是......这是在事务性内存的控制下。 (请阅读STM。)它的观察者是不可知的(取消引用一个原子在deref瞬间返回不可变状态),但可以在事务上进行变异。这正是什么交换!确实。它以事务方式交换新值的旧值。请注意,它与作业有很大不同。分配对于并发是不安全的。
换句话说,atom就像数据库表中的一个单元一样工作。当您查询它时,即使在另一个查询正在更新它的同一时刻,您也会有一个值,而不是例外。
干杯 -