我在理解这些函数如何更新底层引用、原子等时遇到问题。
文档说: (应用当前身份值参数)
(def one (atom 0))
(swap! one inc) ;; => 1
所以我想知道它是如何“扩展到”申请表的。没有提到申请表单中的“args”到底是什么。它是一系列参数还是这些单独的值?
它是否“扩展”为:
(apply inc 0) ; obviously this wouldnt work, so that leaves only one possibility
(apply inc 0 '())
(swap! one + 1 2 3) ;; #=> 7
是吗:
(apply + 1 1 2 3 '()) ;or
(apply + 1 [1 2 3])
(def two (atom []))
(swap! two conj 10 20) ;; #=> [10 20]
是吗:
(apply conj [] [10 20]) ;or
(apply conj [] 10 20 '())
最佳答案
您从 swap!
的文档字符串中引用的段落意味着所发生的情况相当于用 (apply f old- value args)
,其中 args
是传递给 swap!
的所有附加参数的序列。
实际发生的情况有所不同,但这只是一个实现细节。出于好奇:原子有一个名为 swap
的 Java 方法,该方法被重载以接受一到四个参数。第一个始终是 IFn
(传递给 swap!
的 f
);目前,第二个和第三个是该 IFn 的前两个额外参数;第四个(如果存在)是前两个之外的额外参数的 ISeq
。 apply
永远不会涉及,固定数量的情况甚至不会调用 IFn
的 applyTo
方法(它们只是使用 invoke
)。这提高了常见情况下的性能,即没有太多额外参数传递给 swap!
。
关于clojure - 交换!改变和相似,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3057602/