Ruby中如何实现相同入参构建的类实例判定为相等?
实现方案
无需使用单例模式实现该需求。Ruby中对象默认的==判断逻辑是校验两个对象是否为同一内存实例,只需重写类内的相等判断方法,即可实现同构造参数实例判定相等的效果。注意原示例代码存在拼写错误:att_reader正确写法为attr_reader。
基础实现(满足相等判断要求)
重写==方法即可达到预期运行效果:
class Person attr_reader :name def initialize(name) @name = name end def ==(other) return false unless other.is_a?(Person) @name == other.name end end
测试运行结果:
p1 = Person.new('joe') p2 = Person.new('joe') p3 = Person.new('mary') p1 == p2 # true p2 == p3 # false
优化实现(兼容哈希等场景)
如果需要将Person实例作为哈希键使用,建议同时重写eql?和hash方法,避免不同场景下相等判断逻辑不一致:
class Person attr_reader :name def initialize(name) @name = name end def ==(other) return false unless other.is_a?(Person) @name == other.name end def eql?(other) self == other end def hash @name.hash end end
扩展:相同参数始终返回同一实例(享元模式)
如果你最初参考单例模式的目标是「相同参数调用new永远返回同一个内存实例」,可以通过类级别的缓存实现,不需要将new设为私有:
class Person attr_reader :name @instance_cache = {} class << self def new(name) return @instance_cache[name] if @instance_cache.key?(name) instance = super(name) @instance_cache[name] = instance instance end end def initialize(name) @name = name end def ==(other) other.is_a?(Person) && @name == other.name end def eql?(other) self == other end def hash @name.hash end end
该实现下不仅p1 == p2返回true,判断是否为同一内存实例的p1.equal?(p2)也会返回true。
内容的提问来源于stack exchange,提问作者Leonardo Bittencourt Otero
相关产品推荐
相关产品推荐

