我想创建一个可以读取文件的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)
有人有任何建议,谢谢。
答案 0 :(得分:11)
您是否在寻找with-open
,除非有某些原因您想明确使用宏?
(defn read [file-name]
(with-open [reader (BufferedReader. (FileReader. file-name))]
(doseq [line (line-seq reader)] (println line))))
根据ClojureDocs page,它确保在表单末尾关闭阅读器。
希望这有帮助!
答案 1 :(得分:1)
是的,如果我引用“~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%肯定我的回答才有意义。