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

欢迎!请访问 关于 页面以了解更多关于如何使用本网站的信息。

+1
Tools

在遵循 这个指南 的同时尝试运行我的第一个Clojure程序,我遇到了问题。

这是我的基本代码

(ns clojure-noob.core
  (:gen-class))

(defn -main
  "I don't do a whole lot...yet."
  [& args]
(println "Hello, World!"))

(defn train
  []
  (println "Choo choo!")) 

这里是切换命名空间后的结果

clojure-noob.core> (train)

Syntax error compiling at (*cider-repl Clojure/Projects:localhost:49632(clj)*:46:20).
Unable to resolve symbol: train in this context
clojure-noob.core> (-main)
Syntax error compiling at (*cider-repl Clojure/Projects:localhost:49632(clj)*:49:20).
Unable to resolve symbol: -main in this context
clojure-noob.core> 

我遗漏了哪一步?

而且为什么学习曲线这么陡峭?

3 个回答

+1
by

最有可能的情况是,你已经切换到了命名空间,但你的代码还没有被评估。你处于正确的命名空间 但它为空

所以如果你在一个shell中并且用某种方式打开REPL

$ pwd
/home/whoever/programming-clojure
$ tree
.
└── clojure_noob
    └── core.clj

1 directory, 1 file

$ clj
Clojure 1.10.3
user=> (ns clojure-noob.core)
nil

clojure-noob.core=> (train)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: train in this context

clojure-noob.core=> (require 'clojure-noob.core) ;; try to load code'
Execution error (FileNotFoundException) at user/eval4 (REPL:1).
Could not locate clojure_noob/core__init.class, clojure_noob/core.clj or clojure_noob/core.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.

clojure-noob.core=> (System/exit 0) ;; That did not work
$ mkdir src
$ mv clojure_noob/ src/
$ clj
user=> (ns clojure-noob.core)
nil
clojure-noob.core=> (require 'clojure-noob.core) ;;' ask.clojure syntax
nil
clojure-noob.core=> (train)
Choo choo!
nil

那里发生了什么?

  1. Clojure被初始化。加载了clojure.core命名空间,并加载了用户命名空间,引用了核心函数。

  2. 切换到clojure-noob.core命名空间。clojure.core命名空间默认引用(并且还有一些其他东西 - https://clojure.org/reference/namespaces)。然而,Clojure还没有尝试读取clojure_noob/core.clj。

  3. 尝试用require将函数读入clojure-noob.core命名空间。我们遇上了Clojure的经典陷阱 - 它找不到文件。

  4. 我们使用了Clojure禁止使用的知识,即Clojure将添加到类路径中,但不添加$PWD。理论上你可以从文档中找出这个方法,但不要问我哪里能找到,我从没设法理解人们如何设法找到这一点。重新排列目录结构。

  5. 现在它工作了。

我的免费建议:当依赖管理出问题时,直接去ask.clojure.org提问 - 浏览文档或自己尝试解决问题的做法都是浪费时间。这些真的很难以解决,我花了数月时间才感到得心应手。没有哪种语言是完美的。不过,Clojure对坚持下来的人也有回报,一旦设置好命名空间,就会变得很有趣。

by
谢谢 -- 我尝试了,但最后还是得到同样的错误。

让我重新匹配您的目录结构后再试一次。
by
我又试了一次,结果还是一样。

clojure-noob.core=> (train)
在(REPL:1:1)位置编译时出现语法错误。
在此上下文中无法解决符号:train
by
奇怪。没有足够的信息来精确确定出了什么问题,但你可以尝试以下方法:

1] 运行(map println (all-ns))以获取已加载的命名空间列表。可能存在一些错误,函数被加载到了错误的命名空间中。

2] 尝试运行(require 'clojure-noob.core)来检查Clojure能否找到相关文件。

3] 运行 (ns-publics 'clojure-noob.core)以查看命名空间中定义了哪些符号(如果有的话)。

这个错误是Clojure比较简单的一种错误 -- 你处于正确的命名空间,但是(train)不存在。这可能是文件找不到(可以通过require调用进行检查)或者存在拼写错误,函数在导入过程中丢失了。

如果文件可以找到,你需要使用探索性函数进行挖掘,以便有人能帮助你。就像https://clojure.org/reference/namespaces里的那些一样
+1

owenRiddy说的。

我认为你遗漏的步骤是在指南教你编写(train)函数的时候,它告诉你要重新编译文件。

完成之后,保存你的文件并使用C-c C-k在REPL会话中编译当前文件。(你必须编译你的代码,REPL才能意识到你的更改。)现在如果你在REPL中运行(train),它将回显Choo choo!。

这与owenRiddy做的类似。

clojure-noob.core=> (require 'clojure-noob.core)

请参阅官方Clojure指南中的命名空间导航,以获得一些优秀指导。

0

编辑了

使用clj命令行,如果你只是将你粘贴到repl中的内容复制/粘贴

PS C:\Users\joinr> clj
Clojure 1.10.2
user=> (ns clojure-noob.core
         (:gen-class))

(defn -main
  "I don't do a whole lot...yet."
  [& args]
  (println "Hello, World!"))

(defn train
  []
  nil

#'clojure-noob.core/-main
#'clojure-noob.core/train

然后评估(train)和(main)

clojure-noob.core=> (train)
Choo choo!
nil

clojure-noob.core=> (-main)
Hello, World!
nil

一切似乎都很好。你有什么不同的做法吗?

[ed] 我注意到你遵循CFTBT。这是你第一次使用emacs吗?如果是这样,一个更简单的编辑器/设置可能更好,这样你就不必同时学习Clojure和emacs了......(我说的是作为emacs用户,特别是spacemacs,默认Clojure层和最小自定义......)。

...