2012-05-15 62 views
2

我要通過這個article on Tree Visitors in Clojure和整個下面的例子來:步行/ postwalk使用

(def data [[1 :foo] [2 [3 [4 "abc"]] 5]]) 

(walk/postwalk #(do (println "visiting:" %) %) data) 

什麼是postwalk做外在形式?我無法理解它的實用性。如何以及爲什麼使用了街道?任何解釋將不勝感激。

+0

你是從格魯吉亞來的嗎? Murtaz是喬治亞州的一個着名的名字。 –

+0

不是來自印度 – murtaza52

+0

ok :)這可能是西亞地區的通用名稱。抱歉,不主張。 –

回答

4

我不知道你是問什麼#()意思或做什麼的目的(form1 form2)的意思,所以我會回答這兩個問題。

#()是聲明匿名函數的簡寫。當你將某個函數傳遞給另一個函數時,匿名函數很有用。

爲了說明,看這在repl

; define an anonymous function 
user=> #(+ %1 %2) 
#<user$eval68$fn__69 [email protected]> 

; is equivalent to 
user => (fn [a b] (+ a b)) 
#<user$eval1951$fn__1952 [email protected]> 

; furthermore, you could then assign your anonymous function to a var 
(def f #(+ %1 %2)) 

; is equivalent to 
(defn f [a b] (+ a b)) 

user=> (#(+ %1 %2) 1 2) 
3 

user=> (f 1 2) 
3 

%n指的參數的位置的參數的函數,其中n裝置nth參數,從1開始作爲進一步的速記可以使用%至請參閱適用於單個arg匿名函數的第一個參數。這就是你的例子。

所以,你的例子是相當於

(def data [[1 :foo] [2 [3 [4 "abc"]] 5]]) 

(defn f [x] (do (println "visiting:" x) x)) 

(walk/postwalk f data) 

這裏的do是一種特殊形式,其中,從文檔:

(做exprs *) 評估了順序,並返回表達式最後的價值。如果沒有提供表達式,則返回nil。

事實上defn已經有一個隱含的做,所以我上面的例子實際上並不需要做...

; your example is equivalent to: 

(def data [[1 :foo] [2 [3 [4 "abc"]] 5]]) 

(defn f [x] (println "visiting:" x) x) 

(walk/postwalk f data) 
+0

感謝您回答問題。然而,我很抱歉,我想問問什麼是走秀。 – murtaza52

2

我有同樣的問題,今天,找到這個necrotopik。也許以後更好更新。找到這個對clojure api reference

postwalk 功能 用法:(postwalk F體) 執行形式的深度優先,後序遍歷。在 每個子表格上調用f,使用f的返回值代替原來的值。 識別除排序映射之外的所有Clojure數據結構。 與doall一樣消耗seqs。

這也使得example from clojuredocs事情更清晰:

(use 'clojure.walk) 
(let [counter (atom -1)] 
(postwalk (fn [x] 
      [(swap! counter inc) x]) 
       {:a 1 :b 2})) 

    => [6 {2 [[0 :a] [1 1]], 5 [[3 :b] [4 2]]}] 

所以,postwalk替換功能的結果,每一個子窗體。它用於使用新值更新嵌套結構。這就是爲什麼結果函數最後包含x或%的原因。將結果添加到結果會導致更​​加嵌套的結構。

在上面的例子中,它被看作是遍歷嵌套地圖結構的深度。它首先處理地圖中最深的元素,然後繼續向上,然後潛伏到下一個表格,然後再次上升並完成整個表格的最後一步。