`Range #include?`和`Range#cover?`之间有什么区别?

编辑修复了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#cover? 。 为什么Range#include?不能Range#include? 只是Range#cover?的别名Range#cover? 他们有什么区别?

这两种方法的目的是为了做两件稍微不同的事情。 在内部,它们的实现也非常不同。 您可以查看文档中的来源并查看.include?.cover?做得多.cover?

.cover? method与Comparable模块相关,并检查项是否适合排序列表中的端点。 即使项目不在Range隐含的集合中,它也将返回true。

.include? 方法与Enumerable模块相关,并检查项是否实际位于Range隐含的完整集中。 对数字有一些影响 – 整数范围被计为包括所有隐含的Float值(我不知道为什么)。

这些例子可能有所帮助

 ('a'..'z').cover?('yellow') # => true ('a'..'z').include?('yellow') # => false ('yellaa'..'yellzz').include?('yellow') => true 

另外,如果你试试

 ('aaaaaa'..'zzzzzz').include?('yellow') 

你应该注意到它需要更长的时间

 ('aaaaaa'..'zzzzzz').cover?('yellow') 

主要区别在于include检查对象是否是范围元素之一,而cover返回对象是否在边元素之间。 你可以看到:

 ('a'..'z').include?('cc') #=> false ('a'..'z').cover?('cc') #=> true 
 date_range = {:start_date => (DateTime.now + 1.days).to_date, :end_date => (DateTime.now + 10.days).to_date} date_range_to_check_for_coverage = {:start_date => (DateTime.now + 5.days).to_date, :end_date => (DateTime.now + 7.days).to_date} (date_range[:start_date]..date_range[:end_date]).include?((DateTime.now + 5.days).to_date) #true (date_range[:start_date]..date_range[:end_date]).cover?((DateTime.now + 5.days).to_date) #true (date_range[:start_date]..date_range[:end_date]).include?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date]) #true (date_range[:start_date]..date_range[:end_date]).cover?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date]) #false 

最后一行不应该返回true吗?

我问的原因是当我使用include时rubocop会标记冲突吗? 代替封面? 显然,我的逻辑(检查范围是否包含在另一个范围内)不适用于封面?