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

2 回答 2

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。不要害怕提供您正在使用本地范围名称的数据,以帮助您跟踪您正在做的事情。它还可以帮助您避免尝试将真正不想适应的东西塞入线程宏中。

于 2012-08-28T21:02:42.500 回答
1

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

于 2012-11-14T14:48:36.853 回答