Xiu*_* Xu 1 clojure lazy-sequences
我想知道lazy-seq返回有限列表或无限列表.有一个例子,
(defn integers [n]
(cons n (lazy-seq (integers (inc n)))))
Run Code Online (Sandbox Code Playgroud)
当我跑的时候
(first integers 10)
Run Code Online (Sandbox Code Playgroud)
要么
(take 5 (integers 10))
Run Code Online (Sandbox Code Playgroud)
结果是10和(10 11 12 13 14).但是,当我跑
(integers 10)
Run Code Online (Sandbox Code Playgroud)
该过程无法打印任何内容,无法继续.有没有人可以告诉我为什么和laza-seq的用法.非常感谢!
当你说你在跑步的时候
(integers 10)
Run Code Online (Sandbox Code Playgroud)
你真正在做的是这样的:
user> (integers 10)
Run Code Online (Sandbox Code Playgroud)
换句话说,您正在REPL(read-eval-print-loop)中评估该表单.
"读取"步骤将从字符串"(integers 10)"转换为列表(integers 10).非常直截了当.
"eval"步骤将integers在周围的上下文中查找,看到它绑定到一个函数,并使用参数评估该函数10:
(cons 10 (lazy-seq (integers (inc 10))))
Run Code Online (Sandbox Code Playgroud)
由于a lazy-seq直到需要才实现,简单地评估这个形式将导致一个clojure.lang.Cons对象的first元素是,10并且其rest元素clojure.lang.LazySeq尚未实现.
您可以通过简单def(无无限挂起)验证这一点:
user> (def my-integers (integers 10))
;=> #'user/my-integers
Run Code Online (Sandbox Code Playgroud)
在最后的"打印"步骤中,Clojure基本上尝试将刚刚评估的表单的结果转换为字符串,然后将该字符串打印到控制台.对于有限序列,这很容易.它只是继续从序列中取出项目,直到没有任何左边,将每个项目转换为字符串,用空格分隔它们,在末端粘贴一些括号,并且vo:
user> (take 5 (integers 10))
;=> (10 11 12 13 14)
Run Code Online (Sandbox Code Playgroud)
但是正如你已经定义的那样integers,没有剩下任何项目的点(好吧,至少在你得到一个整数溢出之前,但这可以通过使用inc'而不仅仅是补救inc).所以Clojure能够很好地读取和评估你的输入,但它根本无法打印无限结果的所有项目.