## 解構
解構可以用在一個函數或者宏的參數里面來把一個集合里面的一個或者幾個元素抽取到一些本地binding里面去。它可以用在由 `let` special form 或者 `binding` 宏所創建的binding里面。
比如,如果我們有一個vector或者一個list, 我們想要獲取這個集合里面的第一個元素和第三個元素的和。那么可以用下面兩種辦法, 第二種解構的方法看起來要簡單一點。
```
(defn approach1 [numbers]
(let [n1 (first numbers)
n3 (nth numbers 2)]
(+ n1 n3)))
; Note the underscore used to represent the
; second item in the collection which isn't used.
(defn approach2 [[n1 _ n3]] (+ n1 n3))
(approach1 [4 5 6 7]) ; -> 10
(approach2 [4 5 6 7]) ; -> 10
```
&符合可以在解構里面用來獲取集合里面剩下的元素。比如:
```
(defn name-summary [[name1 name2 & others]]
(println (str name1 ", " name2) "and" (count others) "others"))
(name-summary ["Moe" "Larry" "Curly" "Shemp"]) ; -> Moe, Larry and 2 others
```
`:as` 關鍵字可以用來獲取對于整個被解構的集合的訪問。如果我們想要一個函數接受一個集合作為參數,然后要計算它的第一個元素與第三個元素的和占總和的比例,看下面的代碼:
```
(defn first-and-third-percentage [[n1 _ n3 :as coll]]
(/ (+ n1 n3) (apply + coll)))
(first-and-third-percentage [4 5 6 7]) ; ratio reduced from 10/22 -> 5/11
```
解構也可以用來從map里面獲取元素。假設我們有一個map這個map的key是月份, value對應的是這個月的銷售額。那么我們可以寫一個函數來計算夏季的總銷售額占全年銷售額的比例:
```
(defn summer-sales-percentage
; The keywords below indicate the keys whose values
; should be extracted by destructuring.
; The non-keywords are the local bindings
; into which the values are placed.
[{june :june july :july august :august :as all}]
(let [summer-sales (+ june july august)
all-sales (apply + (vals all))]
(/ summer-sales all-sales)))
(def sales {
:january 100 :february 200 :march 0 :april 300
:may 200 :june 100 :july 400 :august 500
:september 200 :october 300 :november 400 :december 600})
(summer-sales-percentage sales) ; ratio reduced from 1000/3300 -> 10/33
```
我們一般使用和map里面key的名字一樣的本地變量來對map進行解構,比如上面例子里面我們使用的 `{june :june july :july august :august :as all}` . 這個可以使用 `:keys` 來簡化。比如, `{:keys [june july august] :as all}` .