解构可以用在宏或者函数的参数列表中,用于将集合中的某些部分提取到局部绑定变量中。解构也可以用在let特殊形式或者bingding宏所创建的绑定变量中。
假设我们定义的某函数接受一个向量或者列表作为参数,需要返回第一个和第三个子元的和。如下所示:
(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记录了每个月的销售额,键表示月份,值表示该月的销售额。函数用于求夏季的销售额占当年销售额的比值,如下:
(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的结构。例如我们在上文中使用的{june :june july :july august :august :as all},可以用keys进行简写,如{:keys [june july august] :as all}。