广州明生堂生物科技有限公司


Ruby中相等性判断的4种方法

网络编程 Ruby中相等性判断的4种方法 06-22

很早就知道 ruby 有 4 种相等性判断方法,分别是:“==”,“===”,“equal?” 和 “eql?”,平常程序中都有使用,但是感觉对其缺乏深入理解,今天读 rails 部分源码的时候拿捏不定其中一个判断的意思,于是趁机深入研究了一番,总算觉得比较清楚了,今天做一下笔记,以作备忘。

“==” 最常见的相等性判断

“==” 使用最频繁,它通常用于对象的值相等性(语义相等)判断,在 Object 的方法定义中,“==” 比较两个对象的 object_id 是否一致,通常子类都会重写覆盖这个方法,通过比较内部值来判断对象是否相等。

比如 ActiveRecord::Base 对 “==” 的定义

def ==(comparison_object)

    super ||

      comparison_object.instance_of?(self.class) &&

      id.present? &&

      comparison_object.id == id

  end

通过 model 的 id 属性比较两个 ActiveRecord::Base 实例是否相等。

“===” 用于 case 语句的相容判断

“===” 主要用于 case 语句中对象的相容比较,看代码比较容易理解。

def what_is(obj)

  case obj

    when /abc/

      puts "include abc"

    when 3..5

      puts "in 3..5"

    when Symbol

      puts "It is a symbol"

    else

      puts "unkonwn"

  end

end

what_is("abcde") # => "include abc" what_is(4) # => "in 3..5" what_is(:a) # => "It is a symbol" what_is(100) # => "unknown"

case 背后是拿每一个 when 后面的对象与 obj 进行 === 方法计算比较,比如上面的代码就是 分别求 /abc/.===(obj) , (3..5).===(obj) , Symbol.===(obj) 。

关键得看 === 方法里如何定义, Class 类中, === 定义为 obj.is_a?(klass),所以 case 可以现实 obj 的类型判断。

特别要注意的是和其他相等判断不同 “===” 通常没法交换,也就是很可能 a.===(b) != b.===(a) ,比如 /abc/ === "abcd" 为 true,但 "abcd" === /abc/ 为 false。

“equal?” 相同对象判断

“equal?” 其实是最简单的,但是也是最容易让人搞混的判断。说它简单是因为这个方法的语义是比较两个对象是否相同(是否有相同的 object_id),Object 的方法适用所有对象,不应该对其重写覆盖。说它容易让人搞混,是因为 ruby 和 java 中 “==” 和 “equal?” 方法的语义正好是相反的,ruby 中 “equal?” 表示对象引用相同,而 java 表示对象值相同。

“eql?” 对象 hash 值判断

eql? 用于对象 hash 值判断,如果两个对象的 hash 值相等,就返回 true,否则返回 false。Object 的定义里,“eql?” 和 “==” 是等价的。通常可以把 “eql?” 看作比 “==” 更严格的相等,比如:

1 == 1.0     #=> true

1.eql? 1.0   #=> false

Rails中使用MySQL分区表一个提升性能的方法
MySQL的分区表是一种简单有效的处理极大数据表的特性,通过它可以使应用程序几乎很少改动就能达成对极大数据表的高效处理,但由于RailsActiveRecord设

Rails应用程序中同时修改操作冲突问题的解决方案
Rails应用程序中操作冲突是一个常见问题,Rails提供了简单有效的解决方法。举一个实际的例子:我们的系统里有一个商店模块,商店中重要的一块是对

Ruby的运算符和语句优先级介绍
Ruby是一种表达能力很强的语言,这得意于它异常丰富的运算符和语法糖,虽然Ruby一直把最小惊讶原则作为它的哲学之一,但还是常常看到让人惊讶不已


编辑:广州明生堂生物科技有限公司

标签:对象,方法,分区表,让人,定义