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

欢迎!请查看关于页面获取更多关于这个网站如何运作的信息。

+1点赞
工具 by

在遵循这个指南的同时尝试运行我的第一个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命名空间已载入,user命名空间已载入,并引用了核心函数。

  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将src/添加到类路径中,但没有添加$PWD。从理论上讲,您可以从文档中解决这个问题,但不要问我怎样,我从未成功地理解过人们应该怎样才能弄清楚这一点。调整目录结构。

  5. 现在它就正常工作了。

我的免费建议:当依赖管理出现问题的时候,直接去ask.clojure.org求助——阅读文档或自己解决问题都是浪费时间。这类问题真的很棘手,我花了数月时间才上手。没有一种语言是完美的。不过,Clojure为坚持下去的人准备了回报,一旦命名空间设置完成,就会变得非常有趣。

谢谢——我试了,但最终仍然出现相同的错误。

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

clojure-noob.core=>(train)
在REPL:1:1处编译时出现语法错误。
在此上下文中无法解析符号:train
奇怪。没有足够的信息来准确诊断问题,但你可以尝试以下方法

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)函数的下面,它告诉你需要重新编译文件

完成之后,保存你的文件并在REPL会话中使用C-c C-k来编译你的当前文件。(你必须编译你的代码,以便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

一切似乎都正常。你做了什么不同的事情?

编辑] 我注意到你遵循CFTBT。这是你第一次使用emacs吗?如果是这样,一个更简单的编辑器/设置可能会更好,这样你就可以同时学习clojure和emacs...(我说这句话是一个emacs用户,尤其是带有默认clojure层和最小定制的spacemacs...)。

...