为什么
(defn tester []
(let [bar #{"a" "b" "c"}]
(+ 1 1)
(map println bar)))
Run Code Online (Sandbox Code Playgroud)
打印
a
b
c
Run Code Online (Sandbox Code Playgroud)
到 emacs cider repl,但不是
(defn tester []
(let [bar #{"a" "b" "c"}]
(map println bar)
(+ 1 1)))
Run Code Online (Sandbox Code Playgroud)
map 是懒惰的,如果您不使用(实现)整个价值,它将避免做不必要的工作。
在 a let(以及在函数和 a 中do)中,最后一个表达式的值是整个表单的值。其他形式被评估并且它们的结果被丢弃:所以(map println bar)被评估——产生一个惰性序列——但是随后这个惰性序列被丢弃而没有意识到其中的值。
如果您想要map副作用函数(例如println)的类似行为,您可以使用run!: (run! println bar)-- 这将急切地消耗序列bar并应用于println每个元素。
注意:如果您使用mapvwhich 是eager而不是lazy,您将得到一个充满nil值的向量——每次调用的结果println——所以你几乎肯定不想这样做。
您也可以使用,doseq但它比run!:
(doseq [item bar]
(println item))
Run Code Online (Sandbox Code Playgroud)