【问题标题】:Can't take value of a macro (clojure)无法获取宏的值(clojure)
【发布时间】:2014-08-13 23:11:48
【问题描述】:

在这段clojure代码中:

(defn makeStructs ;line 27
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   with-open[r (reader (file fName))]
   (let [r 
      res (doall (map makeStruct (line-seq r)))
      ]    
  (. r close)
     res
  ) 
)

我收到此编译器错误:

Exception in thread "main" java.lang.Exception: Can't take value of a macro: #'clojure.core/with-open (clojureHW.clj:27)

上面注释了第 27 行。

知道问题出在哪里吗?

【问题讨论】:

  • @Svante:我很抱歉,但我所上的课程要求我每周学习一门语言,然后用它编写一个广泛的程序。我以前从未使用过 Lisp,因此在这方面很差。教授没有办公时间,否则我会去那里。
  • 每当我尝试新事物时,如果不以看起来像霰弹枪编程的方式重复应用基础知识,我就无法学习基础知识。我经常错误地应用学到的基础知识或应用不正确的推断学习。当我这样做时,有时需要很长时间才能解决问题,但我已经了解了基础知识。然后我通常会尝试一些新的东西。
  • 在 C 中,您可以执行 #define X 4 并在后续行中执行 bar = X; 以得到代码 bar = 4;,但在 Clojure 中,您会执行类似 (defmacro X [] 4) 和其他地方 @987654327 的操作@。所以在最简单的情况下,Clojure 需要做一些额外的工作,但在最困难的情况下……好吧,你根本无法用 C 预处理器来做这些事情。

标签: clojure compiler-errors


【解决方案1】:

你需要实际调用宏,

(defn makeStructs ;line 27
 "..."
 [fName]
   (with-open ; note the extra paren

【讨论】:

  • 它的 anwser 是口齿不清的,但它周围有括号 :)
【解决方案2】:
(defn makeStructs ;line 27
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   with-open[r (reader (file fName))]
   (let [r 
      res (doall (map makeStruct (line-seq r)))
      ]    
  (. r close)
     res
  ) 
)

这行不通,因为

  1. with-open 周围没有括号。这将是一个正常的符号,它不会被调用。
  2. 您的 let 中的表单数量又是奇数。你有 r, res aund (doall ...)。您已经在 with-open 中为 'r' 进行了正确的绑定。你只需要

    (let [res (doall (map makeStruct (line-seq r)))] ....)

  3. 你为什么要这样做(. r close) with-open 宏会为你这样做:http://clojuredocs.org/clojure_core/clojure.core/with-open

所以你得到:

(defn makeStructs 
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   (with-open [r (reader (file fName))]
     (let [res (doall (map makeStruct (line-seq r)))]
        res)))

但是因为你只有一件事让你真的不需要那个:

(defn makeStructs 
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   (with-open [r (reader (file fName))]
     (doall (map makeStruct (line-seq r)))))

Lisp 语言真的很简单,大多数程序员只是想让自己变得困难,因为他们习惯这样做。你有很多问题是因为你已经习惯了像 X 一样工作的东西,但现在它们像 Y 一样工作。尽量不要假设事情像 X 一样工作,你会让你的生活更轻松。

【讨论】:

    【解决方案3】:

    当你看到这个错误时,要添加到你的调试工具包中,我建议你寻找一个没有左括号'('的函数被定义或调用。

    在您的特定情况下,正如其他答案已经指出的那样,您的代码在 with-open 时缺少“(”。

    (defn makeStructs ;line 27
     "open fName as a file and turns each line into a struct. 
      Returns a Vector of structs"
     [fName]
    -->   with-open[r (reader (file fName))]
    

    你没有调用 with-open,而是取了它的值。

    我的错误如下所示:

    --> defn ret-col-match
        "Returns true false match on sequence position w/ cmp-val."
    
        [row cmp-val col-idx]
        (if (= (nth row col-idx nil) cmp-val)
            true
            false))
    

    您可以在定义之前看到缺少的“(”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-05
      • 2023-03-19
      • 2023-02-04
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多