我是一个Java和学习clojure。
clojure中究竟是什么解构?
我可以看到this博客说:
最简单的解构示例是分配a的值 矢量。
user=> (def point [5 7])
#'user/point
user=> (let [[x y] point]
(println "x:" x "y:" y))
x: 5 y: 7
他assigning the values of a vector
的意思是什么?什么是真正的用途?
提前致谢
答案 0 :(得分:2)
point
是一个包含值向量的变量。 [x y]
是变量名称的向量。
当您将point
分配给[x y]
时,解构意味着每个变量都会被赋予值中相应的元素。
这只是一种更简单的写作方式:
(let [x (nth point 0) y (nth point 1)]
(println "x:" x "y:" y))
有关使用解构的其他方法,请参阅Clojure let binding forms。
答案 1 :(得分:2)
术语" Destructuring"声音比它重。
它在视觉上将形状与形状相匹配。例如:
(def nums [1 2 3 4 5 6])
(let [[a b c & others] nums]
;; do something
)
Imagine the effect of the let binding as:
1 2 3 4 5 6
| | | ( )
v v v v
[a b c & others]
;; Now we can use a, b, c, others, and of course nums,
;; inside the let binding:
user=> (let [[a b c & others] nums]
(println a)
(println b)
(println c)
(println others)
(println nums))
1
2
3
(4 5 6)
[1 2 3 4 5 6]
目标是简明集合的名称项目,以便在let绑定或函数的范围内使用(即在"词法范围内")。
为什么"简洁"?好吧,没有解构,let绑定看起来像这样:
(let [a (nth nums 0) ;; or (first nums)
b (nth nums 1) ;; or (second nums)
c (nth nums 2)
others (drop 3 nums)]
;; do something
)
这说明了基本思想。有许多细节(ifs和buts,dos和don&ts;),值得深入阅读。这里有一些资源可以解释更多,例如:
我个人的最爱:Jay Fields关于Clojure Destructuring的帖子: http://blog.jayfields.com/2010/07/clojure-destructuring.html
Braveclojure对解构的温和介绍: http://www.braveclojure.com/do-things/#3_3_3__Destructuring
答案 2 :(得分:2)
这意味着用符号
制作一些数据结构的图片((fn [[d [s [_ _]]]]
(apply str (concat (take 2 (name d)) (butlast (name s)) (drop 7 (name d))) ))
'(describing (structure (of data))))
=> "destructuring"
((fn [[d e _ _ _ _ _ i n g _ _ _ _ _ s t r u c t u r e & etc]]
[d e s t r u c t u r i n g]) "describing the structure of data")
=> [\d \e \s \t \r \u \c \t \u \r \i \n \g]
将这些^示例粘贴到REPL&与他们一起玩,看看它是如何运作的。
答案 3 :(得分:0)
解构通过将每个名称绑定到对象的相应部分,将名称模式绑定到复杂对象。
要绑定到序列,您需要提供名称的向量。例如......
(let [[x y] (list 5 7)] ... )
......相当于
(let [x 5, y 7] ... )
要通过索引查找绑定到地图或向量,您需要提供名称到密钥的地图 对。例如......
(let [{x 0, y 1} [5 7]] ... )
......相当于上述两种情况。
正如其他人所提到的,你可以找到这个强大机制here的完整描述。
答案 4 :(得分:0)
用于命名数据结构的组件,并获取它们的值。
假设你想要一个" person"结构体。在java中,您将一直创建一个包含各种字段的构造函数,getter和setter的类,例如名称,年龄,高度等。
在Clojure中你可以跳过"仪式"并且只是有一个带有3个插槽的向量,首先是名称,而不是年龄,最后是高度。现在你可以简单地命名这些"组件"得到他们的价值观,如下:
(def person ["Fred" 30 180])
(let [[name age height] person]
(println name age height)) ;; will print: Fred 30 180
p.s - 有更好的方法可以让一个人成为"在clojure中(例如记录等),这只是一个了解解构是什么的例子。
答案 5 :(得分:0)
解构是一种便利功能,它允许通过分离复杂的数据结构( seq-ables ,如矢量或关联)轻松创建局部绑定(而不是变量!)像hash-maps一样),如here所述。
采用以下示例:
(let [v [1 2 3 4 5 6]
v_0 (first v)
v_1 (nth v 1)
v_rest (drop 2 v)
m {:a 1 :b 2}
m_a (get m :a)
m_b (get m :b)
m_default (get m :c "DEFAULT")]
(println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
然后可以使用如下的解构绑定简化上面的代码:
(let [[v_0 v_1 & v_rest :as v]
[1 2 3 4 5 6]
{m_a :a m_b :b m_default :c :or {m_default "DEFAULT"} :as m}
{:a 1 :b 2}]
(println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
解构模式可用于let
绑定和函数参数(fn
,defn
,letfn
等),也可用于宏以返回{{1包含这种解构模式的绑定。
要注意的一个重要用法是使用let
和if-let
宏。始终在整个表单上评估when-let
语句,即使结构化绑定本身评估为if
:
nil