Ale*_*ard 5 iteration clojure seq clojure-java-interop
我在clojure中使用java类,它为包含一系列记录的特定于域的二进制文件提供检索API.
java类用文件初始化,然后提供一个.query方法,该方法返回一个只有一个方法的内部类的实例.next,因此不能很好地使用通常的java集合API.外部类和内部类都不实现任何接口.
该.query方法可以返回null而不是内部类.该.next方法返回一个记录字符串,如果没有找到其他记录,则返回null,它可能在第一次调用时立即返回null.
如何在不编写更多java类的情况下使这个java API在clojure中运行良好?
我能想到的最好的是:
(defn get-records
[file query-params]
(let [tr (JavaCustomFileReader. file)]
(if-let [inner-iter (.query tr query-params)] ; .query may return null
(loop [it inner-iter
results []]
(if-let [record (.next it)]
(recur it (conj results record))
results))
[])))
Run Code Online (Sandbox Code Playgroud)
这给了我一个结果向量来处理clojure seq抽象.是否有其他方法可以使用lazy-seq或使用协议从Java API中公开seq?
不下降到lazy-seq:
(defn record-seq
[q]
(take-while (complement nil?) (repeatedly #(.next q))))
Run Code Online (Sandbox Code Playgroud)
相反,(complement nil?)您也可以只使用identityif .nextdoes not return boolean false。
(defn record-seq
[q]
(take-while identity (repeatedly #(.next q))))
Run Code Online (Sandbox Code Playgroud)
我还会稍微重组一下入口点。
(defn query
[rdr params]
(when-let [q (.query rdr params)]
(record-seq q)))
(defn query-file
[file params]
(with-open [rdr (JavaCustomFileReader. file)]
(doall (query rdr params))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
294 次 |
| 最近记录: |