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