问题 Clojure:相当于Common Lisp READ函数?


当我想将存储在文件中的S表达式读入正在运行的Common Lisp程序时,我执行以下操作:

(defun load-file (filename)
  "Loads data corresponding to a s-expression in file with name FILENAME."
  (with-open-file (stream filename)
    (read stream)))

例如,如果我有一个名为的文件 foo.txt 包含S表达式 (1 2 3),如果调用如上,上面的函数将返回该S表达式: (load-file "foo.txt")

我一直在搜索和搜索,并没有在Clojure中找到同样优雅的解决方案。有任何想法吗?

谢谢!


8031
2018-05-18 00:56


起源



答案:


你可以做到,例如

(require '[clojure.contrib.io :as io])

(io/with-in-reader (io/file "foo.txt") (read))
; => (1 2 3)

请注意,您可能想要重新绑定 *read-eval* 至 false 第一。另请注意,上面的内容适用于当前的contrib HEAD(当它发布时几乎肯定会在1.2中工作);对于Clojure 1.1,相同的功能可用于 clojure.contrib.duck-streams 和 clojure.contrib.java-utils 命名空间。


8
2018-05-18 01:18



嗨,这种方法的优点是什么(如果有的话)(read-string(slurp“foo.txt”)) - jkndrkn
slurp / io/slurp* 尽管如此,仍然会将文件的全部内容篡改掉 read-string 只读一整个表格并丢弃其余表格。该 with-in-reader 方法将只读取第一种形式(由于缓冲)。此外,你可以在身体中有更多的形式 with-in-reader;特别是随后的调用 read 在同一个 with-in-reader 表单将从文件中返回更多表单。 (尝试使用 [(read) (read)] 作为获得最初两种形式的身体。)但是,如果我考虑过这个问题,我会把这个答案与你的答案一起发布。 :-) - Michał Marczyk


答案:


你可以做到,例如

(require '[clojure.contrib.io :as io])

(io/with-in-reader (io/file "foo.txt") (read))
; => (1 2 3)

请注意,您可能想要重新绑定 *read-eval* 至 false 第一。另请注意,上面的内容适用于当前的contrib HEAD(当它发布时几乎肯定会在1.2中工作);对于Clojure 1.1,相同的功能可用于 clojure.contrib.duck-streams 和 clojure.contrib.java-utils 命名空间。


8
2018-05-18 01:18



嗨,这种方法的优点是什么(如果有的话)(read-string(slurp“foo.txt”)) - jkndrkn
slurp / io/slurp* 尽管如此,仍然会将文件的全部内容篡改掉 read-string 只读一整个表格并丢弃其余表格。该 with-in-reader 方法将只读取第一种形式(由于缓冲)。此外,你可以在身体中有更多的形式 with-in-reader;特别是随后的调用 read 在同一个 with-in-reader 表单将从文件中返回更多表单。 (尝试使用 [(read) (read)] 作为获得最初两种形式的身体。)但是,如果我考虑过这个问题,我会把这个答案与你的答案一起发布。 :-) - Michał Marczyk


我在这里找到了解决方案: 如何将字符串评估为clojure表达式?

(read-string (slurp "foo.txt"))

抱歉打扰你,伙计们^ _ ^


6
2018-05-18 01:30