使用 update 和 inc 更新原子失败
Updating an atom with update and inc fails
我有一个原子(在 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 (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)))
但是,我想知道为什么第一种形式不起作用。谢谢。
您使用的 Clojure/ClojureScript 是什么版本?我只是尝试以下方法:
project.clj
(defproject cljsdemo "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [[org.clojure/clojure "1.10.0"]
[org.clojure/clojurescript "1.10.520"]]
:main ^:skip-aot cljsdemo.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}}
:plugins [[lein-cljsbuild "1.1.7"]]
:cljsbuild {
:builds [{
;; The path to the top-level ClojureScript source directory:
:source-paths ["src-cljs"]
;; The standard ClojureScript compiler options:
;; (See the ClojureScript compiler documentation for details.)
:compiler {:output-to "public/js/main.js" ;; default: target/cljsbuild-main.js
:optimizations :advanced
:pretty-print false}}]}
src-cljs/foo/demo.cljs
(ns foo.demo)
(def player
(atom {:episode 0 :hello "world"}))
(println
(clj->js
(swap! player update :episode inc)))
public/index.html
<html>
<body>
<h1>Testing...</h1>
<script src="js/main.js"></script>
</body>
</html>
目录结构:
$ tree
.
├── project.clj
├── public
│ └── index.html
└── src-cljs
└── foo
└── demo.cljs
编译代码:lein cljsbuild once
.
然后我启动一个 Web 服务器:cd public; python -m SimpleHTTPServer 3000
并在 Firefox 上打开 http://0.0.0.0:3000/,我在 JavaScript 控制台上看到以下内容:
#js {:episode 1, :hello world}
正如@ez121sl 在评论中指出的那样,函数 update
在代码的其他地方被重新定义,这导致了错误。
我有一个原子(在 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 (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)))
但是,我想知道为什么第一种形式不起作用。谢谢。
您使用的 Clojure/ClojureScript 是什么版本?我只是尝试以下方法:
project.clj
(defproject cljsdemo "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [[org.clojure/clojure "1.10.0"]
[org.clojure/clojurescript "1.10.520"]]
:main ^:skip-aot cljsdemo.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}}
:plugins [[lein-cljsbuild "1.1.7"]]
:cljsbuild {
:builds [{
;; The path to the top-level ClojureScript source directory:
:source-paths ["src-cljs"]
;; The standard ClojureScript compiler options:
;; (See the ClojureScript compiler documentation for details.)
:compiler {:output-to "public/js/main.js" ;; default: target/cljsbuild-main.js
:optimizations :advanced
:pretty-print false}}]}
src-cljs/foo/demo.cljs
(ns foo.demo)
(def player
(atom {:episode 0 :hello "world"}))
(println
(clj->js
(swap! player update :episode inc)))
public/index.html
<html>
<body>
<h1>Testing...</h1>
<script src="js/main.js"></script>
</body>
</html>
目录结构:
$ tree
.
├── project.clj
├── public
│ └── index.html
└── src-cljs
└── foo
└── demo.cljs
编译代码:lein cljsbuild once
.
然后我启动一个 Web 服务器:cd public; python -m SimpleHTTPServer 3000
并在 Firefox 上打开 http://0.0.0.0:3000/,我在 JavaScript 控制台上看到以下内容:
#js {:episode 1, :hello world}
正如@ez121sl 在评论中指出的那样,函数 update
在代码的其他地方被重新定义,这导致了错误。