【发布时间】:2019-05-06 17:42:25
【问题描述】:
我有一个原子(在 ClojureScript 中):
(def player
(atom {:episode 0 ...}))
我想将:episode 加一:
(swap! player update :episode inc)
这在 Lein REPL 中运行良好。
但是,当运行时,它会抛出:
mfp.js:5808 Uncaught Error: No protocol method IDeref.-deref defined for type cljs.core/PersistentHashMap: ...
at Object.cljs$core$missing_protocol [as missing_protocol] (mfp.js:5808)
at Object.cljs$core$_deref [as _deref] (mfp.js:7268)
at cljs$core$deref (mfp.js:9396)
at mfp$update (mfp.js:36808)
at mfp.js:18388
at Function.cljs.core.swap_BANG_.cljs$core$IFn$_invoke$arity$4 (mfp.js:18389)
at cljs$core$swap_BANG_ (mfp.js:18341)
at mfp$next_episode (mfp.js:36946)
at HTMLAnchorElement.<anonymous> (mfp.js:36920)
我可以通过使用更长的形式来解决这个问题:
(swap! player assoc :episode (+ 1 (@player :episode)))
但是,我想知道为什么第一种形式不起作用。谢谢。
【问题讨论】:
-
您似乎正在尝试
swap!取消引用的值而不是原子本身。确保将原子传递给swap!。 -
什么代码不起作用?
(swap! player update :episode inc)应该像你说的那样工作。 -
@Carcigenicate 我非常同意,但是如果
player是一张地图,您确定这是您收到的错误消息吗?对于像我这样更习惯 JVM-clojure 的人来说,它看起来像一个包含哈希图的原子,但传递的函数不是inc- 它是一些试图取消其输入的函数。事实上,我看到 cljs.core/update 直接调用 deref - 就好像有人写了(swap! player update :k deref) -
@amalloy 你是对的。错误的第一行似乎直截了当且很常见,以至于我对其余部分感到震惊。不过,这将是一个更奇怪的错误。
-
实际上,我对第二个不能正常工作的看法是错误的。
swap!允许的“隐式函数”出于某种原因让我失望。我认为切换到 C 语言正在腐烂我的大脑。
标签: clojure clojurescript