6
(defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 10)))

(take 3 (seq-trial))

评估时上面的代码片段打印出以下内容 -

(你好 0 你好 1 你好 2 你好 3 你好 4 你好 5 你好 6 你好 7 你好 8 你好 9 1 2 3)

因为 map 返回一个惰性序列,我希望它只打印 -

(你好 0 你好 1 你好 2 1 2 3)

为什么要在这里评估整个列表?

4

1 回答 1

8

这是因为称为分块的性能优化。本质上,该序列是在称为块的n 个项目的组中实现的。这意味着您需要注意映射函数中的任何副作用。最终结果是正确的,你仍然得到一个正确长度的序列返回

默认块大小为 32,因此如果将范围增加到大于该值的值,您会更好地理解发生了什么:

user> (defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 100)))

user> (take 3 (seq-trial))
hello  0 ; 32 item 'chunk' realized...
hello  1

...

hello  30
hello  31
(1 2 3)  ; the expected returned value

如果您需要避免分块,有可用的选项

于 2013-03-07T10:03:13.580 回答