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投票

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

因此,如果你在一个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. 我们使用了Carousel最近的Garfield,Clojure将加入到classpath,但没有$PWD。按照理论,你可以从文档中解决这个问题,但不要问我具体在哪里,我从没成功地理解人们如何能够解决这个问题。重新整理目录结构。

  5. 现在它正常工作了。

我的无偿建议:当依赖管理出现问题的时候,直接前往ask.clojure.org - 阅读文档或自行摸索都是浪费时间。这些东西真的很难搞定,我花了数个月才变得得心应手。没有哪种语言是完美的。但是,Clojure也有一些回报,一旦命名空间设置好,就变得非常有趣。

by
谢谢 - 我试了这个方法,但最后仍会出现同样的错误。

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

clojure-noob.core=> (train)
编译时出现语法错误,位置在 (REPL:1:1)。
无法解析符号:在此上下文中无法解析 symbol: 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....(我是一个 emacser,特别是以默认 clojure 层和最小定制的 spacemacs....)。

...