(取5(范围))和(范围5)之间有什么区别

时间:2015-12-02 00:30:38

标签: clojure

我刚刚开始学习Clojure,我已经看到了'take'函数在引用范围时的几种用途。

特别是

(take 5 (range))

这似乎与

相同
(range 5)

两者都生成

(0 1 2 3 4)

是否有风格或性能使用其中一种原因?

3 个答案:

答案 0 :(得分:5)

一般来说,使用(range 5)可能会更高效,我认为它更具惯用性。但是,请记住,这需要人们知道创建时范围的范围。

如果最初的尺寸未知,或者在施工后可能会进行其他转换,那么take选项非常好。例如:

(->> (range) (filter even?) (drop 1) (take 5))

答案 1 :(得分:3)

两者都具有相同的性能。因为(范围)函数返回一个懒惰的seq,直到访问元素才实现。根据Danial Higginbotham的着作" Clojure为勇敢和真实的"懒惰的序列   由两部分组成:一个如何实现序列元素的方法,到目前为止已经实现了元素。当您使用(范围)时,它不包含任何已实现的元素   但它确实有生成其元素的方法。每次尝试访问未实现的元素时,lazy seq将使用其配方生成所请求的元素。

这里是解释懒惰seq的链接 http://www.braveclojure.com/core-functions-in-depth/

答案 2 :(得分:1)

范围可以使用以下形式

(range) #or
(range end) #or
(range start end) #or
(range start end step)

所以在这里你可以控制你正在生成的范围并且你正在生成集合 在您的示例中使用(范围)将给出一个惰性序列,将根据需要进行评估,因此您需要5个项目,因此生成了很多项目

虽然使用了像

(take n) #or
(take n coll)

您需要传递要从中获取n个项目的集合