2013-05-30 41 views
3

下lighttable使用rxjava(http://netflix.github.io/RxJava/javadoc/)使用Clojure 1.5.1,請考慮以下(使用副作用的,突變(恐怖)外部集電極從單子提取數據!)Observable/toObservable未找到靜態函數?

(ns expt1.core (:import [rx])) 

(def ^:private collector (atom [])) 
(defn- collect [item] 
    (reset! collector (conj @collector item))) 

(def string-explode (partial map identity)) 

(reset! collector []) 
(-> 
(Observable/toObservable ["one" "two" "three"]) 
(.mapMany #(Observable/toObservable (string-explode %))) 
(.subscribe collect) 
) 

@collector 

產生:

[\o \n \e \t \w \o \t \h \r \e \e] 

我想說

(reset! collector []) 
(-> 
(Observable/toObservable ["one" "two" "three"]) 
(.mapMany (comp Observable/toObservable string-explode)) 
(.subscribe collect) 
) 

但是,驚喜

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to find static field: toObservable in class rx.Observable, compiling:(NO_SOURCE_PATH:93:1) 
      Compiler.java:6380 clojure.lang.Compiler.analyze 
      Compiler.java:6322 clojure.lang.Compiler.analyze 
      Compiler.java:3624 clojure.lang.Compiler$InvokeExpr.parse 
      Compiler.java:6562 clojure.lang.Compiler.analyzeSeq 
      ... 

其實只是

Observable/toObservable 

產生類似異常。 Clojure的爲什麼可以找到Observable/toObservable當它像

#(Observable/toObservable (string-explode %)) 

的表達而不是像

(comp Observable/toObservable string-explode) 

的表達?

+1

如果你想從Observable提取數據,只需使用'Observable/toList'然後'rx.observables.BlockingObservable/single'即可。或者只是'rx.observables.BlockingObservable/getIterator'。 –

回答

4

Observable/toObservable是Java方法,而不是Clojure函數。您不能將Java方法視爲函數值,就像您可以使用Clojure函數一樣。 comp組成Clojure功能(實現IFn接口的對象)。解決方案:將方法調用包裝在Clojure函數中。其他

一兩件事:

(defn- collect [item] 
    (reset! collector (conj @collector item))) 

應該是:

(defn- collect [item] 
    (swap! collector conj item))) 

上的原子僅使用reset!當你不希望使用舊值。當你這樣做時,使用swap!,否則不能保證原子更新(另一個線程可以在讀取它的值後更新原子)。

+0

謝謝你的原子提示。我絕對錯過了那一個! –