2014-06-29 15 views
6

Jestem clojure Java i uczenia się.Co oznacza destrukturyzacja w Clojure?

Co dokładnie demontażu struktury w Clojure?

widzę this blog mówiąc:

Najprostszym przykładem destructuring jest przypisanie wartości do wektorze.

user=> (def point [5 7]) 
#'user/point 

user=> (let [[x y] point] 
     (println "x:" x "y:" y)) 
x: 5 y: 7 

co miał na myśli assigning the values of a vector? Co to naprawdę wykorzystuje?

góry dzięki

Odpowiedz

2

point jest zmienną, która zawiera wektor wartości. [x y] to wektor nazw zmiennych.

Po przypisaniu point do [x y], rozpad oznacza, że ​​zmienne każda uzyskać przypisany odpowiedni element wartości.

To tylko prostszy sposób pisania:

(let [x (nth point 0) y (nth point 1)] 
    (println "x:" x "y:" y)) 

Zobacz Clojure let binding forms dla Innym sposobem wykorzystania rozpad.

+0

Jestem z Java tle, to jest jak tworzenie nowej zmiennej opartej na starych zmiennych? – sriram

+0

Nie znam dobrze języka Java, ale nie sądzę, że ma coś takiego. Nie tworzy nowych zmiennych, to tylko cukier syntaktyczny do wiązania wielu zmiennych naraz z różnych części innej zmiennej. – Barmar

+0

Zobacz zaktualizowaną odpowiedź, pokazującą, co jest równoważne. – Barmar

0

rozpad wiąże wzór nazwy do obiektu złożonego wiązanie każdej nazwy do odpowiadającej części przedmiotu.

Aby powiązać z sekwencją, należy podać wektor nazw. Na przykład ...

(let [[x y] (list 5 7)] ...) 

... jest odpowiednikiem

(let [x 5, y 7] ...) 

do wiązania się z mapie lub do wektora przez indeksu odnośnika, należy przedstawić map wśród pary nazwa-klucz. Na przykład ...

(let [{x 0, y 1} [5 7]] ...) 

... jest odpowiednikiem obu powyższych.

Jak wspominają inni, można znaleźć pełny opis tego potężnego mechanizmu here.

0

jego używane do komponentów nazwa struktury danych i uzyskać ich wartości.

Powiedzmy, że chcesz mieć „osoba” strukturę. W języku Java, możesz przejść całą drogę, aby utworzyć klasę z konstruktorami, pobierającymi i ustawiającymi dla różnych pól, takich jak imię, wiek, wysokość itp.

W Clojure można pominąć "ceremonię" i po prostu mieć wektor z 3 gniazdami, najpierw dla imienia, niż dla wieku i dla wzrostu.Teraz można po prostu wymienić te „elementy” i uzyskać ich wartości, tak jak poniżej:

(def person ["Fred" 30 180]) 
(let [[name age height] person] 
    (println name age height)) ;; will print: Fred 30 180 

ps - istnieją lepsze sposoby, aby „osobą” w Clojure (takie jak rekordy etc), to jest tylko przykład zrozumieć, co robi destrukturyzacja.

2

Termin "destrukturyzacja" brzmi cięższy niż jest.

To jak wizualnie pasujące kształty do kształtów. Na przykład:

(def nums [1 2 3 4 5 6]) 

(let [[a b c & others] nums] 
    ;; do something 
) 

Imagine the effect of the let binding as: 

1 2 3 4 5 6 
| | | ( ) 
v v v  v 
[a b c & others] 

;; Now we can use a, b, c, others, and of course nums, 
;; inside the let binding: 

user=> (let [[a b c & others] nums] 
     (println a) 
     (println b) 
     (println c) 
     (println others) 
     (println nums))  
1 
2 
3 
(4 5 6) 
[1 2 3 4 5 6] 

Celem jest zwięźle przedmiotów nazwa kolekcji, do stosowania wewnątrz zakresu let wiązania lub funkcji (czyli w ramach „zakresu leksykalnego”).

Dlaczego "zwięzły"? Cóż, bez destrukturyzacji przypisanie niech będzie wyglądać następująco:

(let [a (nth nums 0) ;; or (first nums) 
     b (nth nums 1) ;; or (second nums) 
     c (nth nums 2) 
     others (drop 3 nums)] 
    ;; do something 
) 

To ilustruje podstawowy pomysł. Jest wiele szczegółów (ifs i buts, i dos i zakazów), i warto przeczytać dalej, dogłębnie. Oto kilka zasobów, które wyjaśniają więcej, wraz z przykładami:

Mój osobisty faworyt: post Jay Fields w sprawie Clojure destructuring: http://blog.jayfields.com/2010/07/clojure-destructuring.html

łagodne wprowadzenie do demontażu struktury, z Braveclojure: http://www.braveclojure.com/do-things/#3_3_3__Destructuring

2

Oznacza to, tworzenia obrazu struktury niektórych danych z symbolami

((fn [[d [s [_ _]]]] 
    (apply str (concat (take 2 (name d)) (butlast (name s)) (drop 7 (name d)))))  
    '(describing (structure (of data)))) 

=> "destructuring" 

((fn [[d e _ _ _ _ _ i n g _ _ _ _ _ s t r u c t u r e & etc]] 
    [d e s t r u c t u r i n g]) "describing the structure of data") 

=> [\d \e \s \t \r \u \c \t \u \r \i \n \g] 

Pasta^te przykłady w REPL & baw się z nimi, aby zobaczyć, jak to działa.

+0

Podoba mi się to pierwsze zdanie: żywe i zwięzłe. Drat! Dlaczego tego nie powiedziałem. – Thumbnail

0

destructuring to przydatna funkcja umożliwiająca która umożliwia lokalne powiązania (nie zmienne!), Aby łatwo tworzyć przez rozebranie złożonych struktur danych (SEQ-Ables jak wektorami lub associatives jak hash-map), jak to jest opisany here.

Take następujący przykład:

(let [v [1 2 3 4 5 6] 
     v_0 (first v) 
     v_1 (nth v 1) 
     v_rest (drop 2 v) 
     m {:a 1 :b 2} 
     m_a (get m :a) 
     m_b (get m :b) 
     m_default (get m :c "DEFAULT")] 
    (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default)) 

Następnie powyższy kod można uprościć stosując wiązania rozpad jak następuje:

(let [[v_0 v_1 & v_rest :as v] 
     [1 2 3 4 5 6] 
     {m_a :a m_b :b m_default :c :or {m_default "DEFAULT"} :as m} 
     {:a 1 :b 2}] 
    (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default)) 

stanie rozpad może być stosowany w let wiązania i parametrów funkcyjnych (fn , defn, letfn itd.), A także w makrach, aby zwrócić wiązania let zawierające takie wzorce destrukturyzacji.

Jednym z ważnych zastosowań, o którym należy pamiętać, są makra if-let i when-let. Oświadczenie if zawsze jest oceniana na całej postaci, nawet jeśli destrukturyzowaną sami ocenić na nil Wiązania:

(if-let [{:keys [a b]} 
     {:c 1 :d 2}] 
    (println a b) 
    (println "Not this one"))