我想知道lazy-seq会返回有限列表或无限列表。有一个例子,
(defn integers [n]
(cons n (lazy-seq (integers (inc n)))))
当我跑步时
(first integers 10)
或
(take 5 (integers 10))
结果是10和(10 11 12 13 14) 。但是,当我跑
时(integers 10)
该过程无法打印任何内容而无法继续。有没有人可以告诉我为什么和laza-seq的用法。非常感谢你!
答案 0 :(得分:7)
当你说你正在运行时
(integers 10)
你真正在做的是这样的事情:
user> (integers 10)
换句话说,您正在REPL(read-eval-print-loop)中评估该表单。
“读取”步骤将从字符串"(integers 10)"
转换为列表(integers 10)
。很简单。
“eval”步骤将在周围的上下文中查找integers
,看到它绑定到一个函数,并使用参数10
评估该函数:
(cons 10 (lazy-seq (integers (inc 10))))
由于lazy-seq
在需要之前未实现,因此只需评估此表单即可生成clojure.lang.Cons
元素,其first
元素为10
且其{ {1}}元素是尚未实现的rest
。
您可以使用简单的clojure.lang.LazySeq
(无无限挂起)来验证这一点:
def
在最后的“打印”步骤中,Clojure基本上尝试将刚评估的表单的结果转换为字符串,然后将该字符串打印到控制台。对于有限序列,这很容易。它只是继续从序列中取出项目,直到没有任何剩余,将每个项目转换为字符串,用空格分隔它们,在末端粘贴一些括号,并且vo:
user> (def my-integers (integers 10))
;=> #'user/my-integers
但是当你定义user> (take 5 (integers 10))
;=> (10 11 12 13 14)
时,就没有剩下任何项目的点(好吧,至少在你得到整数溢出之前,但是可以通过使用{{}来解决这个问题。 1}}而不仅仅是integers
)。因此,Clojure能够很好地读取和评估您的输入,但它无法打印出无限结果的所有项目。
答案 1 :(得分:0)
当你尝试打印无界延迟序列时,它将被完全实现,除非你限制*print-length*
。
答案 2 :(得分:0)
#define VALUEA "A"
#define VALUEB "B"
#define CHOOSE VALUEA
#define MY_MACRO CHOOSE
// CHOOSE -> VALUEA
// MY_MACRO -> VALUEA
#define TEMP MY_MACRO // save
#undef MY_MACRO
#define CHOOSE VALUEB
#define MY_MACRO TEMP // restore
// CHOOSE -> VALUEB
// MY_MACRO -> VALUEA
宏从不构造列表,有限或无限。它构造了一个lazy-seq
对象。这是一个名义序列,它包含一个无参数的函数(通常称为thunk),在调用时计算为实际序列;但它必须被调用,这就是机制的目的:延迟评估实际的序列。
因此,您可以将评估的 clojure.lang.LazySeq
对象传递给无限序列,前提是您从未实现它们。您在REPL的评估会调用实现,这是一个无休止的过程。
答案 3 :(得分:-1)
它没有返回任何内容,因为你的整数函数会产生无限循环。
(defn integers [n]
(do (prn n)
(cons n (lazy-seq (integers (inc n))))))
使用(integers 10)
进行调用,您将看到它永远计数。