Clojure:了解剂量中的结合

时间:2014-04-13 08:16:33

标签: clojure

我理解以下代码片段及其相应的输出

(let  [ [x y] (map list [1 2] [3 4])]  (prn x) (prn y))
(1 3)
(2 4)
nil

现在,以下输出让我感到困惑:

(doseq [ [x y] (map list [1 2] [3 4])] (prn x y))
1 3
2 4
nil

我认为在上面的代码片段中x将被绑定到[1 3]并且y将被绑定到[2 4]所以输出应该是"

1 2
3 4
nil

2 个答案:

答案 0 :(得分:3)

绑定是在嵌套中拉出较大单个元素内的各个元素。地图创建了一个列表((1 3) (2 4),因此元素1 3是第一个,因此这就是doseq输出的内容:这是" destructuring"并且xy 两者从列表的单个元素中绑定。因此x和y分别为1和3,然后是2和4。

另请注意,这与for中发生的绑定相同,并且解构适用于所有序列类型。

答案 1 :(得分:3)

让我们找出你困惑的根源。

(map list [1 2] [3 4])

评估为

((1 3) (2 4))

所以你的第一个例子

(let [[x y] (map list [1 2] [3 4])]  (prn x) (prn y))

......相当于

(let [[x y] [[1 3] [2 4]]] (prn x) (prn y))

...或者,打印方式略有不同

(let [[x y] [[1 3] [2 4]]] (prn [x y]))

...简化为

(let [z [[1 3] [2 4]]] (prn z))

......按预期生产

; [[1 3] [2 4]]
; nil

到目前为止,这么好。

如果我们归结为令人困惑的例子,

(doseq [ [x y] (map list [1 2] [3 4])] (prn x y))

......以同样的方式,我们得到了,自由打印每个z整体,

(doseq [z [[1 3] [2 4]]] (prn z))

相当清楚地产生观察到的顺序:

[1 3]
[2 4]
nil

区别在于doseqz绑定到[[1 3] [2 4]]中的每个连续向量,因此我们看不到封闭的[ ... ],而let 1}}将z绑定到整个事物。