Ruby中的各种比较运算
Ruby中的各种比较运算
Ruby中设计了很多种比较方式,所有对象都能进行==、!=、===、<=>、eql?、equal?
这几种比较。此外,当实现了<=>
之后,如果还include了Comparable之后,就会自动获得<=、<、==、>=、>、between?
这几个比较方法。
这些比较方法的定义位置和意义分别如下。
在BasicObject中定义了:
==
:比较内容是否相同,更多时候是描述两者是否相等,比如1.0 == 1
的内容是不同的,但是相等,所以返回true!=
:和==
是相反的equal?
:比较对象是否是同一对象,即内存地址是否相同。是最严格的,不应该随意重写这个方法
在Object中定义了:
<=>
:对于Object的<=>
来说,它判断两值是否相等(通过==
比较),如果相等则返回0,如果不等则返回nil。但是,如果重写这个方法,应当如下设计:- 比较两个值的大小,左边大于右边返回1,等于(通过
==
比较)返回0,左边小于右边返回-1 - 如果不可比较,则返回nil
- 比较两个值的大小,左边大于右边返回1,等于(通过
===
:智能比较符号。如果某个类没有重写这个方法(即继承Object的===
),那么它等价于==
,如果重写了,则根据重写规则来判断。通常用于以下几种判断:- Array和String没有实现
===
,所以这两个类中的===
等价于==
的行为 - 对于Range的行为,所定义的是某对象是否在某个Range范围内
- 对于Module的行为,所定义的是某对象是否是某模块的实例或后裔
- 对于Regexp的行为,所定义的是某对象是否能匹配给定模式,等价于
=~
- 所以总结起来,如果某个类定义了
===
,那么它大概是用来做成员所属判断的
- Array和String没有实现
eql?
:对两者计算hash值,比较hash值是否相同。所以,很可能是用来描述内容是否完全一致的判断,比如(1.0).eql?(1)
是false
所以,对于等同性比较来说,它们严格度来说:==
要比eql?
宽松,eql?
要比equal?
宽松。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 骏马金龙!
评论