You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:01:15