我刚刚开始学习Clojure,我已经看到了'take'函数在引用范围时的几种用途。
特别是
(take 5 (range))
这似乎与
相同(range 5)
两者都生成
(0 1 2 3 4)
是否有风格或性能使用其中一种原因?
答案 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个项目的集合