Clojure中的解构(Destructuring)

     解构可以用在宏或者函数的参数列表中,用于将集合中的某些部分提取到局部绑定变量中。解构也可以用在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}。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值