2

我很好奇,所以我检查了交换的源代码!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 ”功能在做什么?我试图搜索它,但它没有在同一个文件中定义,所以找不到它的定义。或者这是另一个实际上根本不是函数的特殊事物?

4

3 回答 3

6

Clojure中的很多东西实际上都是用Java实现的,比如引用类型(atom、ref、var、agent)、数据结构(map、vector、list、set)、命名空间(实际的Namespace类)和其他东西。在阅读Clojure函数的源代码时,经常会发现对Java方法clojure.core的互操作调用。

据我了解,在Clojure本身中实现这些东西是一个长期目标(在此处搜索Clojure-in-Clojure),但现在这些东西是在 中实现的Java,这真的不是那么糟糕,因为整个语言都是开源的并且您可以在 github 存储库中在线检查任何实现细节(已在评论中链接):Clojure(请注意,有一个jvm和一个clj文件夹指示内部代码以何种语言实现)。

于 2013-06-06T20:41:37.630 回答
5

在 Clojure 中,表达式(.x object a b c)会导致方法调用,在 Java 中将表示为object.x(a, b, c). 有关更多详细信息,请参阅Java 互操作

在这种特殊情况下,函数调用作为第一个参数传递的实例swap!的适当重载swap方法。clojure.lang.Atomswap方法包含执行交换的实际逻辑。

于 2013-06-06T21:05:09.400 回答
0

简单地说,一个原子就是某事。这是在事务内存的控制之下。(请阅读 STM。)它的观察者是不可变的(取消引用原子会在 deref 的瞬间返回不可变状态),但可以通过事务进行突变。这正是交换!做。它以事务方式将旧值交换为新值。请注意,它与分配非常不同。分配对于并发来说是不安全的。

换句话说,atom 就像数据库表中的一个单元格一样工作。当您查询它时,您将得到一个值,而不是异常,即使在同一时刻另一个查询正在更新它。

干杯 -

于 2013-06-07T04:01:42.120 回答