clojure data.xml强制计算惰性xml树
根据的自述文件,clojure data.xml强制计算惰性xml树,clojure,Clojure,根据的自述文件,parse返回的数据结构包含惰性序列。因此 (with-open [r (io/input-stream (io/file "data.xml"))] (xml/parse r)) 可能在遍历此代码块外的树时引发异常,因为输入流已关闭 返回之前强制评估整棵树的最优雅方式是什么?我尝试了以下方法,但我想知道是否有更简单的方法 (with-open [r (io/input-stream (io/file "data.xml"))]
parse
返回的数据结构包含惰性序列。因此
(with-open [r (io/input-stream (io/file "data.xml"))]
(xml/parse r))
可能在遍历此代码块外的树时引发异常,因为输入流已关闭
返回之前强制评估整棵树的最优雅方式是什么?我尝试了以下方法,但我想知道是否有更简单的方法
(with-open [r (io/input-stream (io/file "data.xml"))]
(doto (xml/parse r)
(->> (tree-seq map? :content) (dorun))))
对于一般的XML解析,我可以建议。它不是惰性的,并且简化了XML数据的加载。还有类似的名称空间用于解析,还有 对于一般用途,您始终可以回退到。它将递归地遍历一个数据结构,并将每个项目转换为一个普通的映射、向量、集合等。它还将通过
slurp
实现InputStream
(非常方便地测试返回InputStream
而不是字符串的http端点)。它还处理java.lang.Iterable
=>向量。总的来说,unlazy
就像doall
服用类固醇一样
旁白:
如果您想知道map&set之类的东西,那是因为Datomic返回值的行为类似于一个“惰性映射”,并且不会实现它们的所有键值对,除非您专门将每个键提取出来,或者通过
到或类似的方式将对象转储到常规Clojure映射中。对于一般的XML解析,我可能会建议。它不是惰性的,并且简化了XML数据的加载。还有类似的名称空间用于解析,还有
对于一般用途,您始终可以回退到。它将递归地遍历一个数据结构,并将每个项目转换为一个普通的映射、向量、集合等。它还将通过slurp
实现InputStream
(非常方便地测试返回InputStream
而不是字符串的http端点)。它还处理java.lang.Iterable
=>向量。总的来说,unlazy
就像doall
服用类固醇一样
旁白:
如果你想知道map&set之类的东西,那是因为Datomic返回值的行为就像一个“惰性映射”,除非你通过到或类似的方式特别提取每个键或将对象转储到一个常规Clojure映射中,否则不会实现它们的所有键值对。使用doall
强制实现惰性序列,然后只保留第一个元素。此外,您可以使用xml-seq
而不是tree-seq
:
(打开[r(io/输入流(io/文件“data.xml”))]
(->r xml/parse xml seq doall first))
使用doall
强制实现惰性序列,然后只保留第一个元素。此外,您可以使用xml-seq
而不是tree-seq
:
(打开[r(io/输入流(io/文件“data.xml”))]
(->r xml/parse xml seq doall first))
此版本将整个未使用的序列保留在内存中,直到函数返回。这是非惰性序列的必要成本。注意,序列与所需的树共享其数据结构,因此成本可能不会太高。您需要衡量应用程序中的成本。如果内存成本太高,你需要改变策略,拥抱懒惰,而不是试图避免它。@erdos如果你想参与懒惰,您必须使用open
将工作移动到中。此版本在函数返回之前将整个未使用的序列保留在内存中。这是非惰性序列的必要成本。注意,序列与所需的树共享其数据结构,因此成本可能不会太高。您需要衡量应用程序中的成本。如果内存成本太高,你需要改变策略,接受懒惰,而不是试图避免它。@erdos如果你想参与懒惰,你必须用open
将工作转移到你的中。