Clojure-JVM上的函数式编程语言(6) 可变性 作者: R. Mark Volkmann
?原帖地址:http://java.ociweb.com/mark/clojure/article.html#Destructuring
?作者:R. Mark Volkmann
?译者:RoySong
?
可变性(Destructuring)??? 可变性可以用于宏或者函数的参数列表中来提取参数集合的部分进行本地绑定。它同样可以用在let特殊form
或者binding宏中来创建本地绑定。
?
??? 举个例子,假设我们需要一个函数接受一个list或者vector做为参数,返回参数集合的第一和第三个元素相加
的值:
(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关键字能够被用来对具备可变性的集合保持整体访问权限。假设我们需要一个函数接受一个list或者
vector做为参数,返回值是第一个元素加上第三个元素然后再除以所有元素相加的和的结果:
(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是这个月的总销售额。这个函数将夏季月份(6,7,8月)的销售额
相加,再除以整个年度的销售额以获取夏季月份的销售额百分比:
(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的名字相同是一种常用做法。比如,在上面的例子中我们
采用了{june :june july :july august :august :as all}。这实际上可以被简化为
:keys。比如:
{:keys [june july august] :as all}。
?