文章摘要
这篇文章介绍了Ruby中四种比较方法:`==`、`===`、`eql?` 和 `equal?`,并解释了它们在不同场景中的表现和使用方式。以下是总结:
1. **`==`(Equal?)**:
类级别的相等比较,需要在特定类中定义。用于业务逻辑中判断对象是否“相同”。例如,`String`类认为不同内存位置的字符串相同。
示例:
```ruby
a = "abc"
b = a + ""
a == b # => true
```
2. **`===`(Case语句中的比较)**:
等同于在case语句中调用的特定方法,用于判断对象是否为某种类型或满足条件。
示例:
```ruby
case some_object
when /a regex/ => true
when String => true
when 2..4 => true
when lambda => true
end
```
3. **`eql?`(通常意义上的相等)**:
基于对象的值比较,且通常需要通过`alias`方法将`==`方法重命名为`eql?`,以影响哈希表中的比较。
示例:
```ruby
1.eql?(1.0) # => false
```
4. **`equal?`(内存地址相同的对象)**:
通常不应在子类中覆盖,因为这会改变对象在内存中的引用行为。
示例:
```ruby
q = User.first
q.equal?(q) # => false
```
总结:
选择哪种比较方法取决于具体业务需求。使用`==`时应根据类定义实现;使用`===`时用于特定语句;使用`eql?`时可能需要重写以影响哈希表比较;`equal?`通常不应重写。
Ruby里面有4种比较方法,equal?, eql?,==,===,而且在不同的类里面表现的很不一样。在使用的时候也特别容易搞糊涂。 这篇博文将演示一些代码来讲解各个方法。
==- 类意义上的 相等,需要每个类自己定义实现
在特定类中觉得两个对象是否相同,需要看业务上的逻辑表象,所有由程序员覆盖该方法的定义,决定两个对象是否相同。
比如 String 类,他是来计较实际的文字串是否相同,而不在意是否来自同一个内存区域。
>> a=”abc”
#=> “abc”
>> b=a + “”
#=> “abc”
?> a==b
#=> true
>> a.object_id
#=> 70255156346640
>> b.object_id
#=> 70255156340640
===- 用在 case 语句里时会调用的方法
通常用在 case 比较调用该方法,比如
case some_object
when /a regex/
# The regex matches
when String
# some_object is kind of String
when 2..4
# some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
# the lambda returned true
end
等同于
if /a regex/===some_object
# The regex matches
elsif String===some_object
# some_object is kind of object
elsif (2..4)===some_object
# some_object is in the range 2..4
elsif lambda {|x| some_crazy_custom_predicate }===some_object
# the lambda returned true
end
eql? – 通常意义上的 相等
如果两个对象的值相同将返回 true,如果重新定义了子类的==方法,一般需要 alias 到 eql? 方法。 当然也有例外,整数与小数的比较两个方法的返回值就不同。
1==1.0 #=> true
1.eql? 1.0 #=> false
eql? 用在 Hash 里面用来做成员值比较
[1] pry(main)> hash=Hash.new
#=> {}
[2] pry(main)> hash[2]=”a”
#=> “a”
[3] pry(main)> hash[2.0]=”b”
#=> “b”
[4] pry(main)> hash[2]
#=> “a”
[5] pry(main)> hash[2.0]
#=> “b”
[6] pry(main)> hash[2.00]=”c”
#=> “c”
[7] pry(main)> hash[2.0]
#=> “c”
所以什么时候应该覆盖这个方法就看你想让他在 Hash 比较时如何表现。
equal? – 内存地址相同的对象
该方法不应该被子类覆盖
比较的是两个对象在内存中是否相同,是否有同一个object_id值
Rails中及时相同的对象
q=User.first
User Load (40.4ms) SELECT “users”.* FROM “users” ORDER BY “users”.”id” ASC LIMIT 1
#=> #<User id: 1, email: “ryan@wongyouth.com”>
q2=User.first
User Load (0.4ms) SELECT “users”.* FROM “users” ORDER BY “users”.”id” ASC LIMIT 1
#=> #<User id: 1, email: “ryan@wongyouth.com”>
q.equal? q2
#=> false
记忆方法
==按业务需求覆盖该方法 ===覆盖 case 语句时的表现 eql? 别名到==方法, 需要时覆盖方法改变 Hash 比较时的表现 equal? 不改动
您可能感兴趣的文章:Ruby实现命令行中查看函数源码的方法Ruby中的方法(函数)学习总结Ruby中常用的字符串处理函数使用实例ruby中的双等号==问题详解