Ruby 类变量与实例变量中遇到的问题

qinsicheng · 2023年08月29日 · 最后由 qinsicheng 回复于 2023年08月30日 · 857 次阅读

当我想实现一个 (暂不考虑并发性) 单例模式的类时:

class Singleton
  private_class_method :new,:dup,:clone
  def self.instance
    @@single ||= new
  end
end

这时候我再用两个类去继承

class Config < Singleton
end
class Database < Singleton
end
p Config.instance        # => #<Config:0x0000000102a9eef0>
p Database.instance      # => #<Config:0x0000000102a9eef0>
p Config.instance.equal? Database.instance  # => true

当我执行两个继承类各自的.instance方法时,返回了同一个对象,这里我的理解是:

  1. 当执行Config.instance时,找的Singleton.instance并首次初始化类变量@@single,这里的类变量归属Singleton,而@@singleConfig的一个实例。
  2. 当执行Database.instance时,也执行到了Singleton.instance,由于@@single已经被赋值了,所以返回。

但这里我希望的是Config.instanceDatabase.instance各自返回的是各自的实例,所以将@@single改为@single,最终结果确实没问题:

class Singleton
  private_class_method :new,:dup,:clone
  def self.instance
    @single ||= new
  end
end
class Config < Singleton
end
class Database < Singleton
end
p Config.instance          # => #<Config:0x0000000100c8d5b0>
p Database.instance        # => #<Database:0x0000000100c8cae8>
p Config.instance.equal? Database.instance  # => false

但是我搞不明白,为什么变为实例变量@single时,结果发生了变化,@singleSingleton这个对象的实例变量,而这个Singleton这个类对象应该是唯一的,但结果是不同的?想请教一下

Config 往上找祖先,找到 self.instance 方法,然后执行方法的上下文是 Config,@single 属于 Config。

咋不试试自带的单例呢?我觉得会省心一点

class Config
  include Singleton
end

还是目的只是想玩玩类变量?

@@single 是 "类变量",@single 在类方法中是 "类实例变量",在实例方法中是 "实例变量" google 可以找到相关解释

hegwin 回复

单纯是自己想搞明白区别😂

Rei 回复

搞明白了,感谢

geekerzp 回复

感谢感谢

qinsicheng 关闭了讨论。 08月30日 09:50
需要 登录 后方可回复, 如果你还没有账号请 注册新账号