你能给我一些真实的例子 - >宏?

时间:2009-10-22 19:26:06

标签: clojure macros

它似乎是一个强大的宏,但我没有将它应用于任何愚蠢的例子。你能告诉我一些它的实际用途吗?

谢谢!

3 个答案:

答案 0 :(得分:9)

比较

user> (:baz (:bar (:foo {:foo {:bar {:baz 123}}})))
123
user> (java.io.BufferedReader. (java.io.FileReader. "foo.txt"))
#<BufferedReader java.io.BufferedReader@6e1f8f>
user> (vec (reverse (.split (.replaceAll (.toLowerCase "FOO,BAR,BAZ") "b" "x") ",")))
["xaz" "xar" "foo"]

为:

user> (-> {:foo {:bar {:baz 123}}} :foo :bar :baz)
123
user> (-> "foo.txt" java.io.FileReader. java.io.BufferedReader.)
#<BufferedReader java.io.BufferedReader@7a6c34>
user> (-> "FOO,BAR,BAZ" .toLowerCase (.replaceAll "b" "x") (.split ",") reverse vec)
["xaz" "xar" "foo"]
当您想要一种简洁的方式来嵌套调用时,可以使用

->。它允许您按照调用顺序列出调用,而不是从内到外列出调用,这样可以更具可读性。在第三个例子中,注意一些参数与它们所属的函数之间的距离; ->允许您更清晰地对参数和函数调用进行分组。因为它是一个宏,它也适用于Java调用,这很好。

->并不是那么强大,它只会偶尔为你节省一些时间。使用与否是一个风格和可读性的问题。

请查看clojure.zip的底部,了解这有用的极端示例。

(-> dz next next next next next next next next next remove up (append-child 'e) root)

答案 1 :(得分:5)

取自wiki我总是觉得这个例子令人印象深刻:

user=> (import '(java.net URL) '(java.util.zip ZipInputStream))
user=> (-> "http://clojure.googlecode.com/files/clojure_20081217.zip"
           URL. .openStream ZipInputStream. .getNextEntry bean :name)

正如布莱恩所说 - 它不像'不同的风格'那样'有用'。我发现所有java互操作这种形式的'从X开始'然后做Y和Z ...比X的Z到Y更可读。

基本上你有4个选择:

; imperative style named steps:
(let [X something
      b (Y X)
      c (Z b)] c)

; nested calls
(Z (Y X))

; threaded calls
(-> X Y Z)

; functional composition
((comp Z Y) X)

我发现 - &gt;真的很适合java互操作,但在其他地方避免使用它。

答案 2 :(得分:2)

(defn search-tickets-for [term]
  (-> term search zip-soup first :content
    ((partial filter #(= :body (:tag %)))) first :content
    ((partial filter #(= :div (:tag %))))
    ((partial filter #(= "content" ((comp :id :attrs) %))))
    ((partial map :content)) first ((partial map :content))
    ((partial map first)) ((partial filter #(= :ul (:tag %)))) first :content
    ((partial map :content))
    ((partial map first))
    ((partial mapcat :content))
    ((partial filter #(= :h4 (:tag %))))
    ((partial mapcat :content))
    ((partial filter #(= :a (:tag %))))
    ((partial mapcat :content))))
来自#clojure的

clojurebot使用它来搜索组合票