我有一个原子(在ClojureScript中):
(def player
(atom {:episode 0 ...}))
我想将:episode
加1:
(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)))
但是,我想知道为什么第一种形式不起作用。谢谢。
答案 0 :(得分:0)
您正在使用什么版本的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
。
然后,我使用cd public; python -m SimpleHTTPServer 3000
启动Web服务器,并在Firefox上打开http://0.0.0.0:3000/,在JavaScript控制台上看到以下内容:
#js {:episode 1, :hello world}
答案 1 :(得分:0)
正如@ ez121sl在注释中指出的那样,函数update
在代码的其他地方重新定义,从而导致错误。