Clojure 标记的 literals::Raise 错误 - 没有派发宏
Clojure-tagged literals::Raise an error-No dispatch macro for it
tmp2/src/data_readers.clj
{ct/G tmp2.core/foo}
tmp2/src/tmp2/core.clj
(ns tmp2.core)
(defn foo
[x]
(println x "Hello, World!"))
(defn -main
[& args]
(println "Hello, World!")
(foo 123)
(#ct/G "abc"))
在工程目录下"lein run"时,显示结果"abc Hello, World!",但报错
Caused by: java.lang.RuntimeException: No dispatch macro for: c
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:851)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1398)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:1243)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1398)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:1243)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.read(LispReader.java:216)
at clojure.lang.Compiler.load(Compiler.java:7630)
我应该在哪里更改代码?任何帮助将不胜感激
其实这里有两个问题:
1) 你的 foo
函数 returns nil
,reader 函数似乎不能 return 字面值 nil。所以你实际上必须 return 来自 foo
:
的东西
(defn foo [x]
(println x "Hello, World!")
:something)
或者,如果您确实需要在生成的代码中使用 nil
,您可以这样做:
(defn foo [x]
(println x "Hello, World!")
'(quote nil))
2) 第二个问题是您实际上尝试在此处调用标签应用程序的结果:
(#ct/G "abc")
语法 #tag value
在读取时使用 (tag-fn value)
求值,然后将结果直接放入源代码中。当您使用额外的一对括号时,这就是您的情况:
((foo "abc"))
并且,作为 foo
函数 return foo-return-value
,它就变成了 (foo-return-value)
,而这又导致一个错误。
所以,
(defn foo [x]
(println x "Hello, World!")
:nothing)
(defn -main
[& args]
(println "Hello, World!")
(foo 123)
#ct/G "abc")
应该可以工作
好的,成功了。
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn foo
[x]
(println :foo-reader x)
x)
(dotest
(println :test-foo-plain)
(foo 123)
(println :test-foo-reader)
(println #ct/G "abc")
(println :test-leave))
注意数据读取器文件的位置和内容。它必须位于类路径的根目录中。在这种情况下是 src/clj
:
~/expr/demo > cat src/clj/data_readers.clj
{ct/G tst.demo.core/foo}
和测试结果:
> lein test
:foo-reader abc ; <====== NOTICE!
-------------------------------
Clojure 1.10.1 Java 14
-------------------------------
:test-foo-plain
:foo-reader 123
:test-foo-reader
abc
:test-leave
请注意,在读取源代码文件、编译或执行测试之前,标记文字的 foo
reader 被调用。
关于类路径的根目录
Lein 项目由 projects.clj
中的这些条目控制:
:source-paths ["src/clj"]
:java-source-paths ["src/java"]
:test-paths ["test/clj"]
如果你没有 clj
和 java
位(一些项目也将 cljc
和 cljs
文件分割成单独的目录树),你将需要修改 project.clj
或文件位置。
tmp2/src/data_readers.clj
{ct/G tmp2.core/foo}
tmp2/src/tmp2/core.clj
(ns tmp2.core)
(defn foo
[x]
(println x "Hello, World!"))
(defn -main
[& args]
(println "Hello, World!")
(foo 123)
(#ct/G "abc"))
在工程目录下"lein run"时,显示结果"abc Hello, World!",但报错
Caused by: java.lang.RuntimeException: No dispatch macro for: c
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:851)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1398)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:1243)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1398)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:1243)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.read(LispReader.java:216)
at clojure.lang.Compiler.load(Compiler.java:7630)
我应该在哪里更改代码?任何帮助将不胜感激
其实这里有两个问题:
1) 你的 foo
函数 returns nil
,reader 函数似乎不能 return 字面值 nil。所以你实际上必须 return 来自 foo
:
(defn foo [x]
(println x "Hello, World!")
:something)
或者,如果您确实需要在生成的代码中使用 nil
,您可以这样做:
(defn foo [x]
(println x "Hello, World!")
'(quote nil))
2) 第二个问题是您实际上尝试在此处调用标签应用程序的结果:
(#ct/G "abc")
语法 #tag value
在读取时使用 (tag-fn value)
求值,然后将结果直接放入源代码中。当您使用额外的一对括号时,这就是您的情况:
((foo "abc"))
并且,作为 foo
函数 return foo-return-value
,它就变成了 (foo-return-value)
,而这又导致一个错误。
所以,
(defn foo [x]
(println x "Hello, World!")
:nothing)
(defn -main
[& args]
(println "Hello, World!")
(foo 123)
#ct/G "abc")
应该可以工作
好的,成功了。
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn foo
[x]
(println :foo-reader x)
x)
(dotest
(println :test-foo-plain)
(foo 123)
(println :test-foo-reader)
(println #ct/G "abc")
(println :test-leave))
注意数据读取器文件的位置和内容。它必须位于类路径的根目录中。在这种情况下是 src/clj
:
~/expr/demo > cat src/clj/data_readers.clj
{ct/G tst.demo.core/foo}
和测试结果:
> lein test
:foo-reader abc ; <====== NOTICE!
-------------------------------
Clojure 1.10.1 Java 14
-------------------------------
:test-foo-plain
:foo-reader 123
:test-foo-reader
abc
:test-leave
请注意,在读取源代码文件、编译或执行测试之前,标记文字的 foo
reader 被调用。
关于类路径的根目录
Lein 项目由 projects.clj
中的这些条目控制:
:source-paths ["src/clj"]
:java-source-paths ["src/java"]
:test-paths ["test/clj"]
如果你没有 clj
和 java
位(一些项目也将 cljc
和 cljs
文件分割成单独的目录树),你将需要修改 project.clj
或文件位置。