【发布时间】:2016-10-05 16:10:34
【问题描述】:
编辑:
dosync 为自己创建一个函数,因此对 recur 的调用被解释为对函数 dosync 的调用。
这是我实际制作的函数的足迹。我认为尽量保持简单。
(defn change-to-ref [ref data]
(dosync
(if-let [[new-ref new-data] (some-test @ref data)]
(recur new-ref new-data)
(alter ref f data))))
例外:
CompilerException java.lang.IllegalArgumentException:
Mismatched argument count to recur, expected: 0 args, got: 2
原文:
我试图按如下方式更新 ref 中的哈希图
(def example-ref (ref {:some {:nested {:structure}}}))
(defn f [this] [this]) ;; just an example function
(sync (alter example-ref update-in [:some] f)
user=> nil
这很令人惊讶,因为它应该返回了
user=> {:some [{:nested {:structure}}]}
所以比我尝试的要多:
(update-in @example-ref [:some] f)
user=> {:some [{:nested {:structure}}]}
但是比我读到的altercalls apply 所以:
(apply update-in @example-ref '([:some] f))
user=> {:some nil}
好的,让我们以正确的方式来做吧:
(apply update-in @example-ref (list [:some] f))
user=> {:some [{:nested {:structure}}]}
很好,我想通了,
但它并没有解释为什么这在alter 中出错了
反正我也改不了...
(apply (fn [a b] (update-in a b f)) @example-ref '([:something]))
user=> {:some [{:nested {:structure}}]}
它看起来很糟糕,但至少它可以工作,我可以为alter模拟它:D
(sync (alter example-ref (fn [a b] (update-in a b f)) [:some])
user=> nil
好吧,你赢了。
我看了看:
clojure.lang.Ref.alter source
但并没有变得更聪明。 (除此之外,据我了解,alter 实际上并没有调用apply)
我希望你们中的一些人会理解这一点,并知道什么是正确的代码。
【问题讨论】:
-
在
dosync中使用recur是什么意思?你真的想要嵌套事务吗? -
@OlegTheCat 我确实是的,我有一个嵌套的 refs 结构,并且想在路径中找到最后一个,所以我改变它,问题是通过确保有一个函数来解决在 dosync 中调用。
-
@OlegTheCat 顺便说一句,我同意你的问题,如果我会运行交易然后重复发生,那不是一个好主意,因为我认为交易总是一个单一的(在尾部位置)这很好,如果我制作了一个单独的纯函数来搜索路径,也许会更好
标签: clojure hashmap apply stm update-in