Clojure:利用Java互操作限制保持纯洁性
我有一段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.)] (
(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再次修复,谢谢。