2012-08-28 150 views
2

我正在學習clojure。我的問題是可以在( - >)裏面使用(case)。 例如,我想是這樣的(這個代碼不工作):切換箭頭運算符

(defn eval-xpath [document xpath return-type] 
     (-> (XPathFactory/newInstance) 
     .newXPath 
     (.compile xpath) 
     (case return-type 
      :node-list (.evaluate document XPathConstants/NODESET) 
      :node (.evaluate document XPathConstants/NODE) 
      :number (.evaluate document XPathConstants/NUMBER) 
     ) 
    )) 

還是會更好地使用多方法呢?什麼是正確的clojure方式呢?

謝謝。

回答

4

箭頭宏( - >)只是重寫其參數,以便將第n個窗體的值作爲第n + 1個窗體的第一個參數插入。什麼你寫等同於:

(case 
    (.compile 
    (.newXPath (XPathFactory/newInstance)) 
    xpath) 
    return-type 
    :node-list (.evaluate document XPathConstants/NODESET) 
    :node (.evaluate document XPathConstants/NODE) 
    :number (.evaluate document XPathConstants/NUMBER) 

在一般情況下,你可以選擇的三種形式之一使用let是你的尾巴形式的時間提前,然後跟帖說在穿線宏的結尾。像這樣:

(defn eval-xpath [document xpath return-type] 
    (let [evaluator (case return-type 
        :node-list #(.evaluate % document XPathConstants/NODESET) 
        :node #(.evaluate % document XPathConstants/NODE) 
        :number #(.evaluate % document XPathConstants/NUMBER))] 
    (-> (XPathFactory/newInstance) 
     .newXPath 
     (.compile xpath) 
     (evaluator)))) 

但是,你真正想要做的是將關鍵字映射到XPathConstants上的常量。這可以通過地圖來完成。考慮以下內容:

(defn eval-xpath [document xpath return-type] 
    (let [constants-mapping {:node-list XPathConstants/NODESET 
          :node XPathConstants/NODE 
          :number XPathConstants/NUMBER}] 
    (-> (XPathFactory/newInstance) 
     .newXPath 
     (.compile xpath) 
     (.evaluate document (constants-mapping return-type))))) 

您有關鍵字到常量的映射,所以使用Clojure的數據結構來表示它。此外,線程宏的真正價值在於幫助您編譯xpath。不要害怕給你使用本地範圍名稱的數據來幫助你跟蹤你正在做的事情。它還可以幫助您避免嘗試將事情擰入真正不適合的線程宏。