请在2024 Clojure状态调查中分享您的想法!

欢迎!请查看关于页面以了解更多关于如何使用本页面的信息。

+1 投票
REPL

将eduction提供给repl将按列表格式打印结果

=> (eduction (map identity) [#'+ 2 3]) (#'clojure.core/+ 2 3)

这不应该评估为5,因为eduction不是一个序列。然而,当我尝试时,我期望得到返回的eduction,但结果是从REPL中的读者那里得到的意外错误

=> (eval (eduction (map identity) [#'+ 2 3])) 执行错误 (IllegalArgumentException) 在 user$eval183/<clinit> (REPL:1) 中。找不到合适的构造器用于类 clojure.core$map$fn__5880

这个错误的堆栈跟踪似乎表明错误发生在读者中
`
java.lang.ExceptionInInitializerError

at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at clojure.lang.Compiler$ObjExpr.eval(Compiler.java:5000)
at clojure.lang.Compiler.eval(Compiler.java:7180)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at user$eval181.invokeStatic(NO_SOURCE_FILE:1)
at user$eval181.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:7181)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at clojure.main$repl$read_eval_print__9110$fn__9113.invoke(main.clj:437)
at clojure.main$repl$read_eval_print__9110.invoke(main.clj:437)
at clojure.main$repl$fn__9119.invoke(main.clj:458)
at clojure.main$repl.invokeStatic(main.clj:458)
at clojure.main$repl_opt.invokeStatic(main.clj:522)
at clojure.main$main.invokeStatic(main.clj:667)
at clojure.main$main.doInvoke(main.clj:616)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:40)

由:java.lang.IllegalArgumentException: 找不到合适的构造器用于类 clojure.core$map$fn__5880

at clojure.lang.Reflector.invokeConstructor(Reflector.java:288)
at clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1317)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:853)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.read(LispReader.java:216)
at clojure.lang.LispReader.read(LispReader.java:205)
at clojure.lang.RT.readString(RT.java:1879)
at clojure.lang.RT.readString(RT.java:1874)
at user$eval183.<clinit>(NO_SOURCE_FILE:1)
... 27 more

`

clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1317) 的源代码中,它似乎正在处理一个列表形式,其中第一个元素以点字符结束。这是意外的

1 答案

+2 投票

一般来说,并非所有对象都可以被评估。当评估此类对象时,会生成一个如同(fn* [] <eduction-object>)的类。为了创建这个类,那个eduction对象需要被存储在字节码中。在这种情况下,转换函数不能直接存储在字节码中——编译器在这种情况下进行了冒险尝试,将其打印为字符串“#=(clojure.core$map$fn__596.)”。然后这个值在评估过程中试图被读取,但该构造函数中并没有这个类。这就是你所看到的读取错误。

这和在宏中返回对象而不是形式时常见的异常是一样的,实际上你也可以通过宏来复现这个错误(这是一个常见的宏错误)

(defmacro foo [] (eduction (map identity) [#'+ 2 3]))
(foo)

我不知道我是否期望它会工作——正如你所说,eductions是集合,但不是seqs或lists。

by
这很有道理,谢谢。我真的很好奇“clojure.core$map$fn__596.”是从哪里来的。
...