Estoy trabajando en clojure con una clase java que proporciona una API de recuperación para un archivo binario específico de dominio que contiene una serie de registros.Interoperación de clojure a con API iterativa no estándar API
La clase java se inicializa con un archivo y luego proporciona un método .query
que devuelve una instancia de una clase interna que tiene solo un método .next
, por lo que no funciona bien con la API java collections habitual. Ni la clase externa ni la interna implementan ninguna interfaz. El método .query
puede devolver nulo en lugar de la clase interna. El método .next
devuelve una cadena de registro o nulo si no se encuentran registros adicionales, puede devolver nulo inmediatamente después de la primera llamada.
¿Cómo hago para que esta API de Java funcione bien desde clojure sin escribir más clases de Java?
Lo mejor que podía llegar a decir:
(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))
[])))
Esto me da un vector de los resultados de trabajar con las abstracciones clojure seq. ¿Hay otras maneras de exponer un seq de la API de Java, ya sea con lazy-seq o usando protocolos?
Esta es una pregunta interesante, pero ¿qué quiere decir con una API Java no estándar? – octopusgrabbus
@octopusgrabbus específicamente me refiero a que el código de Java no proporciona un java.util.Iterator ni implementa java.lang.Iterable. Lógicamente, el código java proporciona iteración pero no tiene conexión con la API estándar para hacerlo. –