编辑修正了toro2k的评论。
Range#include?
和Range#cover?
看起来是不同的,正如在源代码1、2中所看到的,并且它们在效率上是不同的。
t = Time.now
500000.times do
("a".."z").include?("g")
end
puts Time.now - t # => 0.504382493
t = Time.now
500000.times do
("a".."z").cover?("g")
end
puts Time.now - t # => 0.454867868
从源代码来看,Range#include?
似乎比Range#cover?
更复杂,为什么Range#include?
不能简单地作为Range#cover?
的别名呢?
4条答案
按热度按时间slhcrj9b1#
这两个方法的设计目的是做两件略有不同的事情。它们的内部实现也非常不同。您可以查看文档中的源代码,发现
.include?
比.cover?
做得更多.cover?
方法与Comparable
模块相关,它检查一个项目是否适合排序列表中的端点。即使该项目不在Range
隐含的集合中,它也将返回true。.include?
方法与Enumerable
模块有关,它检查一个项是否真的在Range
所隐含的完整集合中。对数值做了一些微调-整数范围被视为包括所有隐含的Float
值(我不知道为什么)。以下示例可能会有所帮助:
另外,如果你尝试
你应该注意到它需要的时间比
zqry0prt2#
主要区别是
include
检查的是object是否为range元素之一,cover返回的是object是否在edge元素之间,可以看到:u0sqgete3#
最后一行不是应该返回true吗?
我问这个问题的原因是当我用include?代替cover?时,rubocop标记了一个冲突。很明显,我的逻辑(检查范围是否包含在另一个范围中)不适用于cover?。
7ajki6be4#
cover?
和include?
之间存在巨大的性能差异:使用日期范围时要特别小心基于上述理由:
cover?
只检查参数是否在范围的开始和结束之间;在include?
中,你检查你的参数**是否在范围内,这涉及到检查范围内的每一个元素,而不仅仅是开始/结束。让我们运行一个简单的基准测试。
结果:
如您所见,使用
#cover?
是 * 即时的 *;您可以在0.000ms内获得结果。但是,使用
#include?
几乎需要 *5.5秒 * 才能获得相同的结果。仔细选择。