【问题标题】:Clojure: Lein run unable to resolve symbolClojure:Lein 运行无法解析符号
【发布时间】:2014-05-18 00:06:59
【问题描述】:

我刚开始使用 lein 进行我的第一个 clojure 项目,代码在这里:

(ns fileops.core
  (:use
    [clojure.core :only (slurp)]
    [clojure-csv.core :only (parse-csv)]
    [fileops.core]))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (read-file "sample.csv"))

(defn read-file
  "open and read the csv file"
  [fname]
  (with-open [file (clojure.java.io/reader fname)]
    (parse-csv (slurp fname))))

我尝试使用“lein run”运行它,但我不断收到此错误:

Caused by: java.lang.RuntimeException: Unable to resolve symbol: read-file in this context
    at clojure.lang.Util.runtimeException(Util.java:219)
    at clojure.lang.Compiler.resolveIn(Compiler.java:6874)
    at clojure.lang.Compiler.resolve(Compiler.java:6818)
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6779)
    at clojure.lang.Compiler.analyze(Compiler.java:6343)
    ... 52 more

我做错了什么?

【问题讨论】:

  • read-file 应该在源代码中的 main 之前。
  • @DiegoBasch 你是救生员。我是 Clojure 的新手,我花了太多时间试图弄清楚为什么我收到关于在错误上下文中调用我的函数的错误。就是这样……一直都是这样。很棒的帖子。

标签: clojure


【解决方案1】:

使用了来自 clojure 核心的 slurp,这意味着您现在无法使用所有其他核心功能 :) 尝试将您的 ns 更改为使用 :require 而不是 :use,如这是更惯用的。

需要注意的一点是,在 clojure 中顺序确实很重要,因此如果您不在文件顶部声明函数,如在 C 和其他一些语言中,早期的函数将无法引用他们。这就是之前导致您的错误的原因,也是我喜欢在底部定义我的 -main 函数的原因。这是风格问题。

另一件事是您的 -main 函数现在正在使用变量 args 而不是使用它们。在 Clojure 中,使用 _ 来引用未使用的参数是惯用的。您可以使用 & _ 来避免错误消息,因为当用户传入不必要的参数时,但我只会从一开始就使用无参数的 -main 函数。这是因为运行程序时不需要向 main 提供任何内容,而错误确实使调试更容易。很高兴知道正在使用什么以及在哪里使用。 sample.csv 文件已经提供并且正在调用read-file,因此如果您的read-file 函数正确并且sample.csv 文件位于正确的位置,则程序应该运行。

关于您的-main 函数,最好在其中进行一些测试以查看它在运行时是否正确执行,因此我将其更改为将 csv 文件的内容打印到您的控制台上。这种从文件打印的方式是有效的,并且值得单独研究。

最后,确保在 project.clj 文件中包含 clojure-csv.core

core.clj:

(ns fileops.core
  (:require
    [clojure-csv.core :refer [parse-csv]]))

(defn read-file
  "open and read the csv file"
  [fname]
  (with-open [file (clojure.java.io/reader fname)]
    (parse-csv (slurp fname)))) 

 (defn -main []
        (println (clojure.string/join "\n" (read-file "resources/test.csv"))))

project.clj:

...

:dependencies [[org.clojure/clojure "1.5.1"]
               [clojure-csv/clojure-csv "2.0.1"]
                ...]
:main fileops.core

您需要将fileops.core 声明为:main,如上所示。这告诉 Leiningen 当您输入 lein run 时要执行什么函数。非常重要和棘手的东西。

现在请确保您位于项目目录的根目录中,并在终端运行以下命令:

lein clean
lein deps 
lein run 

祝你好运!

延伸阅读:

8th light blog on name-spaces

flying machine studios explanation of lein run

【讨论】:

    【解决方案2】:

    read-file 应该在你的源代码中的 main 之前,或者你应该在 -main 之前放一个这样的声明原因:

    (declare read-file)
    

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2011-10-10
      • 2016-12-31
      相关资源
      最近更新 更多