Clojure

在 REPL 中编程:故障排除

本节列出了使用 REPL 时常见的问题以及如何诊断它们

调用未定义的 Var

症状

user=> my-nonexistent-name
Syntax error compiling at (REPL:0:0).
Unable to resolve symbol: my-nonexistent-name in this context

解释

  • 也许您在 Var 名称中拼错了,例如您应该写 my-non-existent-name 而不是 my-nonexistent-name

  • 也许您忘记在 REPL 中定义 my-non-existent-name(例如使用 defdefn):如果您在代码文件中写了 (def my-non-existent-name …​) 但忘记在 REPL 中执行它,则可能会发生这种情况。

  • 也许您定义了 my-non-existent-name,但在另一个命名空间中。您应该写 myapp.ns23/my-non-existent-name 或者切换到命名空间 myapp.ns23/my-non-existent-name

使用缺失的命名空间别名

症状

user=> ns3/foo-bar
Syntax error compiling at (REPL:0:0).
No such namespace: ns3

解释

  • 也许您在命名空间别名中拼错了,例如您应该写 n3/foo-bar 而不是 ns3/foo-bar

  • 也许您从未在当前命名空间中定义过 ns3 别名:您可以通过执行 (require '[myapp.ns3 :as ns3]) 来解决这个问题。

  • 也许您定义了 ns3 别名,但在与您当前 REPL 所在的命名空间不同的命名空间中。

引用未加载的命名空间

症状

$ clj
Clojure 1.10.0
user=> clojure.set/union
Syntax error (ClassNotFoundException) compiling at (REPL:0:0).
clojure.set

解释

您正在使用尚未在 REPL 中创建的命名空间。请注意,错误消息(‘ClassNotFoundException’)在这种情况下特别令人困惑:原因是 Clojure 编译器在没有找到名为 clojure.set 的已加载命名空间的情况下,尝试将 clojure.set 解释为 Java 类。解决方案是确保 clojure.set 库 已加载.

尝试加载不存在的命名空间

症状

user=> (require '[a.b.c])
Execution error (FileNotFoundException) at user/eval161 (REPL:1).
Could not locate a/b/c__init.class, a/b/c.clj or a/b/c.cljc on classpath.

解释:Clojure 没有找到名为 a.b.c 的现有命名空间,然后在类路径中搜索定义它的 ,最终以上面的异常失败。原因可能会有所不同

  • 也许您只是在命名空间名称中拼错了

  • 也许您忘记将库添加到您的类路径中,这通常通过将其添加到项目的依赖项配置中(例如在 deps.ednproject.clj 文件中)来完成,有时(取决于项目管理工具)运行安装命令(例如 lein deps)。

  • 也许您确实将库添加到了类路径中,但这是在您启动 REPL 之后:在这种情况下,您应该重新启动 REPL。