2013-08-30 19 views
2

之間的協議,我有一個交叉的命名空間的協議:如何共享的Clojure和ClojureScript

(ns xxx.shared.interfaces) 

(defprotocol ITimer 
    (seconds [timer] "Return time in seconds since timer began")) 

我有Clojure的實現:

(ns xxx.time 
    (:require [xxx.shared.interfaces :refer [ITimer]])) 

(defrecord Timer [start-nanos] 
    ITimer 
    (seconds [timer] (double (/ (- (System/nanoTime) (:start-nanos timer)) 
           1000000000)))) 

的問題是,當我使用此代碼在一些Clojure代碼中,要求xxx.time命名空間與:refer :all它抱怨它找不到seconds

Unable to resolve symbol: seconds in this context 

首先,是否有可能以這種方式共享協議?

其次,任何想法我可以使這項工作?

第三,這實際上是一種很好的方式去關於這種代碼共享?理想情況下,我也想分享這個記錄,但它依賴於Java代碼,所以我需要將其分解爲一個函數。這會是一個更好的方式來解決這個問題嗎?

謝謝!

回答

6

secondsxxx.shared.interfaces定義,所以這是你所需要的:require/:use才能夠稱之爲:

(ns foo 
    (:require [xxx.shared.interfaces :refer [seconds]])) 

;; (seconds ...) will now work 

要精心,一個defprotocol表達式創建無功控股協議,底層JVM接口在JVM端(在ClojureScript端沒有對應的)和每個協議方法的Var。協議方法可以通過這些Vars調用,就像其他Clojure函數一樣。

當您爲記錄/類型實現協議時,與您在xxx.time命名空間中執行的操作一樣,如果您實際上未調用方法,則甚至不需要拉入這些Vars(提供實現的單獨問題)。同樣,需要調用協議方法的名稱空間,但並不太在意它調用的對象的特定類型,只需要拉入協議定義的名稱空間並使用相關的Vars,而不需要:require任何實施的名稱空間。

+2

至於代碼共享的問題,我認爲可以共享任何作爲共享代碼的東西並分析協議方法的平臺特定實現當然是使更多代碼可共享的有效方法。是否值得這可能取決於實際避免多少重複。無論如何,如上所述,原始問題與共享無關。 –