论坛首页 编程语言技术论坛

比较Ruby中一些很相似的方法

浏览 2636 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-02-28  

1、kind_of?, is_a?, instance_of? 的区别

 

obj.kind_of? (klass)  ->  true or false

判断klass是否是obj的类,或者超类,或者被mixin的模块

 

obj.is_a? (klass)  ->  true or false

kind_of? 一样

 

obj.instance_of? (klass)  ->  true of false

判断obj是否是由klass生成的实例

 

测试代码:

module Mother; end

class Father
	include Mother
end

class Son < Father; end

son = Son.new

son.kind_of? Son         # true
son.kind_of? Father      # true
son.kind_of? Mother      # true

son.is_a? Mother         # true

son.instance_of? Son     # true
son.instance_of? Father  # false
son.instance_of? Mother  # false

 

2、==, ===, equal?, eql? 的区别

 

这四个方法可以说都有细节区别,但从效果可以粗略地分为两类,一是比较两者是不是引用自同一个对象,二是比较两者的值是否相同。

 

obj == other_obj  ->  true or false

在Object类层面,这个方法是判断obj和 other_obj是不是同一个对象(可以理解为两者的object_id一定要相同)。但通常子类都会重写 == 方法来加入自己的比较逻辑。虽然每个子类都对此有不同的实现,但常见的作用就是比较两个对象的值是否相同。

 

obj === other_obj  ->  true or false

主要用于case语句中的比较。效果和 == 一样,但一般会被子类重写,来适应case语句的需要。很典型的就是正则表达式的 === 方法。

 

obj.equal? (other_obj)  ->  true or false

判断obj和other_obj的object_id是否相同。子类不会重写这个方法。所以它的效果在任何对象中都是一样的

 

obj.eql? (other_obj)  ->  true or false

判断obj和other_obj的值是否相同。和 == 差不多,但有些细微区别,比如Numeric类型,1.eql?(1.0) 是返回 false 的,因为两者类型不同,而 == 则会做类型转换再比较。

 

测试代码:

ary1 = %w{cat dog}
ary2 = %w{cat dog}

# 测试 ==
ary1 == ary2     # true
1 == 1.0         # true

# 测试 equal?
ary1.equal? ary2 # false
1.equal? 1       # true  相同的整型数的object_id也相同,这点和Symbol类似

# 测试eql?
ary1.eql? ary2   # true
1.eql? 1         # true
1.eql? 1.0       # false  类型不同

# 测试 ===
/string/ == "string"  # false
/string/ === "string" # true  为了case语句的比较而改写了Regexp的===方法

Symbol.class_eval do
  # 改写Symbol的===方法,使之可以等于相同“内容”的字符串
  def ===(value)
    value.is_a?(String) ? self.to_s == value : super
  end
end

case "string"
when :string # 这里就会调用:string === "string",成功匹配
  true
else
  false
end

 

3、Array#to_a, Array#to_ary 的区别

 

这里只以 Array 的对象来作比较。因为只有这个类同时实现了这两个方法。从作用而言,它们都是返回一个和原数组内容相同的数组。但细节还是有区别的。

 

arr.to_ary   ->  ary

这个方法很简单,直接返回方法调用者。返回值和原对象没有区别。

 

arr.to_a   ->  arr

这个方法复杂一点。首先,当arr是Array的实例时,直接返回arr;当arr是Array子类的实例时,会先使用 to_ary 获得一个数组,然后根据这个数组创建一个新数组(就是复制)返回。

 

测试代码:

a = [1, 2, 3]
a.to_a.equal? a   # true  因为就是返回自身
a.to_ary.equal? a # true

class SubArray < Array; end

b = SubArray.new
b.to_a.equal? b   # false  因为是Array的子类,所以新数组是复制过的
b.to_ary.equal? b # true
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics