Clojure的for宏接受两个参数:一系列绑定表单和一个正文表达式.因此,如果我想在循环中做多个事情,我必须在do块中包含多个表达式以使它们成为单个表达式.
相比:
(doseq [a (range 3)]
(prn 'a a)
(inc a))
Run Code Online (Sandbox Code Playgroud)
至:
(for [a (range 3)]
(prn 'a a)
(inc a))
Run Code Online (Sandbox Code Playgroud)
在doseq按预期工作.在for抱怨:
clojure.lang.ArityException: Wrong number of args (3) passed to: core/for
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么这不起作用?为什么没有Clojure的设计师(S)允许在多个"身体"表达式循环,就像他们的确在doseq和when?这不像是有任何语义模糊,对吧?
A. *_*ebb 14
Clojure for不是循环,它是懒惰列表理解.由于只do返回(隐式)主体中最后一个表达式的值,因此只有副作用才能存在任何其他表达式.副作用的执行是工作doseq,这就是它隐含的原因do.这for不应该是一个提醒,你真的想要在你的懒惰序列中产生副作用吗?尽管有合理的理由这样做,但需要注意的是,这些副作用会在您需要时执行.
(def foo (for [a (range 32)]
(do
(prn (str "a is " a))
(inc a))))
(take 1 foo)
;=>
("a is 0"
"a is 1"
...
"a is 31"
1) ; <= the return value
(take 10 foo)
;=>
(1 2 3 4 5 6 7 8 9 10) ; aw, no side effects this time
Run Code Online (Sandbox Code Playgroud)