【问题标题】:Clojure macro to read a fileClojure 宏读取文件
【发布时间】:2023-03-04 02:39:02
【问题描述】:

我想创建一个可以读取文件的 Clojure 宏,当文件被成功读取时,应该关闭流。

(import '(java.io FileReader File))

(defmacro read([x y]
`(let ~x 
  (try ~y 
   (. x close)
    (catch Exception e# e#))))) 

这样称呼,

(read [stream (java.io.FileReader (java.io.File "somefile.txt"))] (. stream read)))

导致此错误

java.lang.Exception: No such var: user/x (NO_SOURCE_FILE:8) 

大家有什么建议吗,谢谢。

【问题讨论】:

  • 您能否提供有关您收到的错误消息的更多信息?是运行时错误还是编译时错误?
  • @PieterBreed java.lang.Exception: 没有这样的 var: user/x (NO_SOURCE_FILE:8)
  • 在您的宏的第 4 行,“x”没有被引用。这个还是有很多问题的……
  • 是的,如果我引用 "~x",则会引发此异常

标签: macros clojure


【解决方案1】:

您不是在寻找with-open,除非出于某种原因您想显式使用宏?

(defn read [file-name]
  (with-open [reader (BufferedReader. (FileReader. file-name))]
    (doseq [line (line-seq reader)] (println line))))

根据ClojureDocs page,它确保阅读器在表单末尾关闭。

希望对您有所帮助!

【讨论】:

  • 它是否执行类似于 with-open 的功能?或者你想做一些截然不同的事情?如果它是相同的,可能值得阅读源代码,如果你想阅读它,我链接到的 ClojureDocs 页面包含函数的源代码......
【解决方案2】:

是的,如果我引用 "~x",则会引发此异常

<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: close for class clojure.lang.PersistentVector>

这是因为'~x" 现在指的是[stream (FileReader. (File. "somefile.txt"))]。你得到的错误是有道理的。宏吐出试图在上述向量上调用close() 的代码。您可以尝试使用(first ~x)

请注意,此宏非常通用,不会显着减少用户必须编写的代码量。

您可以尝试这些方法(这可能行不通)

(import '(java.io FileReader File))

(defmacro read([fname]
`(try
   (let [stream# (FileReader. (File. ~fname))
         rtnval (. stream# read)]
     (do 
       (. stream# close)
       rtnval))
   (catch Exception e# e#)))

但我只有 50% 的把握我的回答有意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    相关资源
    最近更新 更多