切换箭头操作员

时间:2012-08-28 20:29:05

标签: clojure

我正在学习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方式?

谢谢。

2 个答案:

答案 0 :(得分: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。不要害怕提供您使用本地范围名称的数据,以帮助您跟踪您正在做的事情。它还可以帮助您避免尝试将事情搞砸到真正不想适合的线程宏中。

答案 1 :(得分:1)

查看以下clojure库以使用xpath表达式:https://github.com/kyleburton/clj-xpath