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