以下摘录自“Clojure的喜悦”:
使用时创建可能无限的整数序列会发生什么 迭代,每次生成新值时打印一个点,然后使用其中任何一个 休息或旁边返回序列的前三个值?和...之间的不同 在下面的例子中可以看到rest和next:
(def非常懒惰( - >(迭代#(do(print。)(inc%))1) 休息休息)) ; => ..#'用户/非常-懒惰
(def less-lazy( - >(迭代#(do(print。)(inc%))1) 下一个下一个))) ; => ...#“用户/不太懒惰
如图所示,下一个版本打印三个点,而其余版本仅打印 二。当从另一个构建一个懒的seq时,rest不会导致计算 (或实现)任何超出其需要的元素;接下来呢。为了确定 seq是否为空,接下来需要检查是否至少有一件事 它,因此可能导致一个额外的实现。这是一个例子:
(println(first very-lazy)); 0.4
(println(first less-lazy)); 4
以下是我在“Cursive IDE”REPL中的内容:
(def very-lazy (-> (iterate #(do (print \.) (inc %)) 1)
rest rest rest))
..=> #'user/very-lazy
(def less-lazy (-> (iterate #(do (print \.) (inc %)) 1)
next next next))
..=> #'user/less-lazy
(println (first very-lazy)) ; .4
.4
=> nil
(println (first less-lazy)) ; 4
.4
=> nil
我想我确实理解了不同行为的解释,但为什么输出在我的REPL中是相同的?
答案 0 :(得分:6)
Clojure 1.7.0中iterate
的实现发生了变化。在1.7之前,它是以cons
和lazy-seq
的形式实现的,它展示了你引用的JoC片段中描述的行为。从1.7开始,它是以专用的clojure.lang.Iterate
类实现的,它以相同的方式处理rest
和next
,因此它的行为与您在REPL中发现的一样。