请考虑以下内容:
class Aaa
attr_accessor :a, :b
end
x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2
puts x == y #=>false
有没有一种方法可以检查相同类型的类中所有公共属性是否相等?
class Aaa
attr_accessor :a, :b
def ==(other)
return self.a == other.a && self.b == other.b
end
end
x = Aaa.new
x.a,x.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
z = Aaa.new
z.a,z.b = 1,3
x == y # => true
x == z # => false
Struct
或 OpenStruct
已经内置了这些类型的情况。 - yurisichAaa = Struct.new(:a, :b)
x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2
x == y #=> true
Struct
定义了==
,eql?
和hash
方法,使得如果两个Aaa
对象的a
和b
的值相等,则它们相等。它还定义了initialize
方法,让您在创建对象时可以选择传入a
和b
的值(Aaa.new(value_for_a, value_for_b)
)。它还定义了to_a
方法以返回[a,b]
。
您还可以使用Struct.new
与块一起定义其他方法,因此您具有“普通”类的全部功能:
Aaa = Struct.new(:a, :b) do
def c
a+b
end
end
Aaa.new(23,42).c #=> 65
Struct.new
只是类的工厂方法。如果您使用class
关键字定义Aaa
,然后自己定义==
等,您将获得完全相同的行为。 - sepp2kclass Aaa
def initialize(a,b,c)
@a, @b, @c = a, b, c
end
end
x = Aaa.new(1,2,3)
y = Aaa.new(1,2,3)
z = Aaa.new(1,2,3)
arr = [x,y,z]
x.instance_variables.map do |v|
arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
#=>true
将z
更改为:
z = Aaa.new(1,2,4)
那么:
x.instance_variables.map do |v|
arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
#=> false
在 Ruby 中处理对象比较的另一种方法是使用 hash
。出于性能原因,当类很大时,最好使用 hash
来比较 Ruby 对象,如下所示:
class Aaa
attr_accessor :a, :b
def intialize(value_a,value_b)
@a = value_a
@b = value_b
end
def hash(target)
@a.hash == target.a.hash && @b.hash == target.b.hash
end
end
A = new Aaa('whatever','whenever')
B = new Aaa('however','whoever')
A.hash(B)