读入表达式 - 阅读时的EOF - 在Clojure中

时间:2014-02-11 22:26:18

标签: clojure

我想在Closure中读取一个包含正确LISP语法的(更长)文件。所以我认为最好的方法是避免使用字符串。我试着使用以下功能:

(defn my-reader 
    [filename]
    (with-open [r (java.io.PushbackReader. (reader filename))]
        (binding [*read-eval* false]
            (loop [expr (read r :eof :end)]
                (if (= :end expr)
                    (print "The End")
                    (do
                        (println expr)
                        (recur (read r :eof :end))))))))

但是,这会在读取错误时抛出EOF。

作为一种解决方法,我已经构建了:

(defn my-reader 
    [filename]
    (with-open [r (java.io.PushbackReader. (reader filename))]
     (binding [*read-eval* false]
        (loop [expr (read r :eof :end)]
            (if (= -1 expr)
                (print "The End")
            (recur (try 
                (print (read r :eof :end))
                (catch Exception e -1))))))))

但那很难看。我在How to use clojure.edn/read to get a sequence of objects in a file?的帮助下尝试了:

(defn my-reader 
    [filename]
    (with-open [r (java.io.PushbackReader. (reader filename))]
        (binding [*read-eval* false]
            (let [expr (repeatedly (partial read r :eof :theend))]
    (dorun (map println (take-while (partial not= :theend) expr)))))))

并且两者都不起作用(阅读时EOF)。但是,另一个线程中的解决方案工作正常(edn似乎是读取文件的首选方法)。不过,我想知道为什么我的尝试不起作用。

1 个答案:

答案 0 :(得分:3)

clojure.core / read的语义与clojure.tools.reader.edn / read略有不同。

arity-3版本带参数

  1. stream输入流
  2. eof-error?一个布尔值,指定您是否希望read在EOF处抛出异常
  3. eof-value在达到EOF时返回的哨兵值
  4. 因此,我认为您希望将(read r :eof :end)替换为(read r false :end),因为关键字是真实的。