Clojure:利用Java互操作限制保持纯洁性

Clojure:利用Java互操作限制保持纯洁性,java,clojure,functional-programming,Java,Clojure,Functional Programming,我有一段Clojure代码,它遵循第三方Java库中定义的,如下所示: (defrecord RecordHandler [] RecordListener (onMsg [this msg] (getValue msg))) (defn read [file] (let [decoder (Decode.) broadcaster (MsgBroadcaster. decoder) handler (RecordHandler.)] (

我有一段Clojure代码,它遵循第三方Java库中定义的,如下所示:

(defrecord RecordHandler []
  RecordListener
  (onMsg [this msg] (getValue msg)))

(defn read
  [file]
  (let [decoder (Decode.)
        broadcaster (MsgBroadcaster. decoder)
        handler (RecordHandler.)]
    (.addListener broadcaster handler)
    (.run broadcaster file)))
我希望在调用
onMsg
时能够收集每条记录的结果。我的主要限制是
Decode
MsgBroadcaster
RecordListener
接口都是由第三方库定义的,
onMsg
返回
void

如何在保持纯净的同时收集每个广播到
RecordHandler
的值?我目前的解决方案是将向量引用传递给
RecordHandler
的初始化,并使用
alter
conj
,但这是在修改引用,这似乎违反了不修改外部状态的思想

(defrecord RecordHandler [memo]
  RecordListener
  (onMsg [this msg] 
    (dosync
      (alter memo conj (getValue msg))))

(defn read
  [file]
  (let [decoder (Decode.)
        broadcaster (MsgBroadcaster. decoder)
        memo (ref [])
        handler (RecordHandler. memo)]
    (.addListener broadcaster handler)
    (.run broadcaster file)))

也许我遗漏了什么,但是必须从事务中调用
alter
,我在您的代码中没有看到。您是正确的。为了简化示例,这是手写的。添加它以避免混淆。谢谢。好的,但现在看来您为
RecordListener
接口的
dosync
方法定义了一个实现?鉴于您描述的约束,我看不到一种不涉及某种可变状态的方法。您所做的对我来说听起来很好。@nha再次修复,谢谢。也许我遗漏了什么,但是必须从事务中调用
alter
,我在您的代码中没有看到。您是正确的。为了简化示例,这是手写的。添加它以避免混淆。谢谢。好的,但现在看来您为
RecordListener
接口的
dosync
方法定义了一个实现?鉴于您描述的约束,我看不到一种不涉及某种可变状态的方法。你所做的对我来说听起来很好。@nha再次修复,谢谢。