clojure解构(clojure destructuring)

来源:互联网 发布:asp库存管理系统源码 编辑:程序博客网 时间:2024/05/02 04:46

【转】http://rritw.com/a/JAVAbiancheng/JAVAzonghe/20130615/370731.html

由于在clojure中如果只靠一些集合到操作函数如first、last、nth等函数,不能够简洁的获取一些嵌套集合中的元素,所以需要destructuring来使我们可以简洁快速的去获取集合中的元素。

由于在clojure中如果只靠一些集合到操作函数如first、last、nth等函数,不能够简洁的获取一些嵌套集合中的元素,所以需要destructuring来使我们可以简洁快速的去获取集合中的元素。 clojure支持的结构有:有顺序集合(sequential collection)的解构和map的解构。

 一、Sequential destructuring 有序集合包括:clojure的list,vector以及sequence。所有实现java.util.List接口的集合:java数组、字符串 

1、根据位置对应来解构

(def v [42 "foo" 99.2 [5 12]])(let [[xyz] v]  (+ xz));= 141.2;;使用下划线占位(let [[x _ _ [yz]] v]   (+ xyz));= 59

2、收集剩余的元素(Gathering extra-positional sequential values​​) 
;;使用&来收集(let [[x & rest] v]   rest);= ("foo" 99.2 [5 12])

3、保留解构的值(retaining the destructured value) 
;;使用as来保留解构的值(let [[x _ z :as original-vector] v]   (conj original-vector (+ xz)));= [42 "foo" 99.2 [5 12] 141.2]


二、Map destructuring 可以进行map解构的类型有:   clojure hash-map,array-map,record。   所有实现java.util.Map接口的集合   支持get函数获取相应值的对象,如:clojure vector,string,array1、位置对应来解构 

(def m {:a 5 :b 6         :c [7 8 9]         :d {:e 10 :f 11}        "foo" 88        42 false});;注意:这里key不单是:key类型,也可以是其他类型(let [{a :ab :b} m]   (+ ab));= 11;;注意:如果是数组、字符串或vector,解构的key是下标(let [{x 3 y 8} [12 0 0 -18 44 6 0 0 1]]   (+ xy));= -17;;顺序解构和map解构混合(let [{[x _ y] :c} m]   (+ xy));= 16(def map-in-vector ["James" {:birthday (java.util.Date. 73 1 6)}]);= #'user/map-in-vector(let [[name {bd :birthday}] map-in-vector]  (str name " was born on " bd));= "James was born on Thu Feb 06 00:00:00 EST 1973"

2、保留解构的值(retaining the destructured value) 
和顺序解构一样用as来保存。 
(let [{r1 :x r2 :y :as randoms}       (zipmap [:x :y :z] (repeatedly (partial rand-int 10)))](assoc randoms :sum (+ r1 r2)));= {:sum 17, :z 3, :y 8, :x 9}

3、默认值(Default values​​) 
(let [k :unkown x :a        :or {k 50}       m]  (+ kx));;= 55     

4、绑定值到对应的key上(binding values​​ to their key's name) 
;;这里的可以用:keys、:strs、:syms来指定key的类型;;但是通常使用:keys类型;;在很多框架中,经常会看到:keys,:or,:as的组合使用(def chas {:name "Chas" :age 31 :location "Massachusetts"}) (let [{name :name age :age location :location} chas]  (format "%s is %s years old and lives in %s." name age location)) ;= "Chas is 31 years old and lives in M​​assachusetts."

5、对剩余部分像map一样解构(Destructuring rest sequences as map key/value pairs) 
;;这个代码太乱,有洁癖的人受不鸟(def user-info ["robert8990" 2011 :name "Bob" :city "Boston"])(let [[username account-year & extra-info] user-info       {:keys [name city]} (apply hash-map extra-info)]   (format "%s is in %s" name city));= "Bob is in Boston";;如果剩余部分的参数个数是偶数个的话,可以用map解构;;有洁癖的人现在觉得世界清静多了(let [[username account-year & {:keys [name city]}] user-info]   (format "%s is in %s" name city));= "Bob is in Boston"


最后,虽然以上的例子只是用let,但是解构用在fn、defn等地方都是可以的。 
    

参考文档:《clojure programming》 

原创粉丝点击