2017-06-29 49 views
5

我学习的Clojure,并阅读有关doseq时,我注意到在official Clojure docdoseq了解Clojure的绑定语法

(doseq [x [-1 0 1] 
     y [1 2 3]] 
    (prn (* x y))) 

我的困惑像下面的例子是表达[x [-1 0 1] y [1 2 3]]

这是否意味着一个绑定表达式?我尝试了一些谷歌搜索的数量,但不能遇到任何描述这种形式的文档。

有人能帮助我了解为Clojure的结合形式的各种语法交涉?

+2

clojuredocs。 org不是任何形式的clojure文档的官方来源。这是用户贡献的不同质量的示例。该网页上的唯一官方的就是'doseq'的文档字符串,它告诉你是读了'for'的文档字符串,以了解它是如何工作的。我同意,如果'doseq'有它自己的详尽文档,但至少它指出你阅读正确的东西会更好。 – amalloy

回答

8

这是一个“binding form"”,它依次将表达式中的值“绑定”到名称x,所以它通俗地表示一个表达式,它将名称绑定到值上,这是“解构绑定表单”的一部分,它绑定名称复合值的部分,如列表或地图

术语“绑定”而不是“设置”有助于传达它在做什么和在某些其他编程语言中设置变量之间的区别。为它花费的doseq内的形式来运行时的值,则该名称被释放到附接至另一个值。

Clojure中提供任意结构的结合给名字在语言指定名称(绑定符号)

(doseq [[x1 x2] [[-1 -1] [0 0] [1 1]] 
     y [1 2 3]] 
    (prn (* x1 x2 y))) 

也是绑定表达式虽然显得稍微深入到数据和受让人大多数地方价值的任何部分名称为第一个向量中的每个项目的两个值(并假定每个项目中有两个数字)我非常喜欢this tutorial on destructuring/binding

+0

真的,我就改成与至少两个数字” –

+0

感谢这个详细的解释序列的序列。它可以帮助! –

2

它就像Java中的嵌套for循环。你也可以做的嵌套“手动”:

(dotest 
    (newline) 
    (println "version 1") 
    (doseq [x [1 2] 
      y [:a :b :c]] 
    (println x y)) 

    (newline) 
    (println "version 2") 
    (doseq [x [1 2]] 
    (doseq [y [:a :b :c]] 
     (println x y)))) 

with results: 
version 1 
1 :a 
1 :b 
1 :c 
2 :a 
2 :b 
2 :c 

version 2 
1 :a 
1 :b 
1 :c 
2 :a 
2 :b 
2 :c 

注意doseq总是返回nil,且仅产生副作用(如打印到屏幕)好。

for表达的行为类似,但返回值的(懒惰)序列(请注意,我们生成在每个环路中的矢量[x y]):

(newline) 
(println "For generates a (lazy) sequence:" 
    (for [x [1 2] 
     y [:a :b :c]] 
    [x y])) 

与结果:

For generates a (lazy) sequence: ([1 :a] [1 :b] [1 :c] [2 :a] [2 :b] [2 :c]) 
+0

+1描绘替代形式。但是,后并没有真正回答我的问题。我目前更关注的是Clojure的绑定语法比替代形式,因为我学习语言,在这个阶段uncerstanding语法是我的首要任务。 –