交换!改变和相似

mek*_*kka 4 clojure

我在理解这些函数如何更新底层ref,atom等时遇到问题.

文档说:(应用f current-of-identity args)

(def one (atom 0))
(swap! one inc) ;; => 1
Run Code Online (Sandbox Code Playgroud)

所以我想知道如何"扩展"到申请表格.没有提到申请表中究竟是什么'args'.它是一系列参数还是这些独立的值?

是"扩大"到:

(apply inc 0) ; obviously this wouldnt work, so that leaves only one possibility
(apply inc 0 '())


(swap! one + 1 2 3) ;; #=> 7
Run Code Online (Sandbox Code Playgroud)

是吗:

(apply + 1 1 2 3 '()) ;or
(apply + 1 [1 2 3])

(def two (atom []))
(swap! two conj 10 20) ;; #=> [10 20]
Run Code Online (Sandbox Code Playgroud)

是吗:

(apply conj [] [10 20]) ;or
(apply conj [] 10 20 '())
Run Code Online (Sandbox Code Playgroud)

Mic*_*zyk 6

你从swap!文档字符串引用的段落意味着所发生的事情相当于交换从旧的那个获得的Atom的新值(apply f old-value args),其中args传递给所有其他参数的seq swap!.

实际发生的情况有所不同,但这只是一个实现细节.为了好奇:Atoms有一个叫做Java的方法swap,它被重载以从一到四个参数中获取.第一个总是一个IFn(f传递给swap!); 目前,第二个和第三个是前两个额外的论点IFn; 第四个,如果存在的话,是ISeq前两个之外的额外争论.apply从不参与和固定元数的情况下,甚至不调用IFnapplyTo方法(它们只使用invoke).在没有传递太多额外参数的常见情况下,这可以提高性能swap!.