运行此按预期工作:
(defn long-seq [n]
(lazy-seq (cons
(list n {:somekey (* n 2)})
(long-seq (+ n 1)))))
(take 3 (long-seq 3))
; => ((3 {:somekey 6}) (4 {:somekey 8}) (5 {:somekey 10}))
不过,我愿做同样的事情用一个向量:
(defn long-seq-vec [n]
(lazy-seq (into
(vector (list n {:somekey (* n 2)}))
(long-seq-vec (+ n 1)))))
(take 3 (long-seq-vec 3))
这给了我一个堆栈溢出。 为什么?
其主要原因是, 载体是不懒惰 -这样的into
呼叫贪婪地消耗由产生的递归序列long-seq-vec
并导致堆栈溢出。 由于这一推论,这是不可能创造无限向量(一般来说,你只能当它是懒惰或环创建了无限数据结构)。
它的工作原理在第一个例子,因为cons
是相当愉快的行为时,懒洋洋地在consing一个懒惰的序列的前面,所以这个顺序可以是无限的。
假设你真正想要的矢量的无限序列我建议是这样的:
(defn long-seq-vec [n]
(lazy-seq (cons
(vector n {:somekey (* n 2)})
(long-seq-vec (+ n 1)))))
(take 3 (long-seq-vec 3))
=> ([3 {:somekey 6}] [4 {:somekey 8}] [5 {:somekey 10}])
或作为替代,你可以使用for
,这本身就是懒惰:
(defn long-seq-vec [n]
(for [x (iterate inc n)]
(vector x {:somekey (* x 2)})))
我喜欢这个,因为它避免了lazy-seq
/ cons
样板,避免递归是在表达你的功能是什么稍微更清晰......这是一个有点多“的声明:”如果你喜欢。 您也可以使用map
以类似的方式。