【问题标题】:Ruby class variable initial value [duplicate]Ruby类变量初始值[重复]
【发布时间】:2017-01-21 05:34:06
【问题描述】:

PHP我写:

Class Test{
  public $a=100;
}

$a=new Test();
echo $a->a; //prints 100

它打印100,但是当我写的时候是红宝石:

class Test
  @a=100
  attr_accessor :a
end

a=Test.new
puts a.a #=> prints nil

a 为 nil,它打印出nil。为什么?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    你有点混淆了。

    您使用@a = 100 定义的是一个类实例变量

    您将通过attr_accessor :a 访问的是一个实例变量 @a

    实例变量使用示例:

    class A
      def initialize a
        @a = a
      end
      attr_accessor :a
    end
    
    instance = A.new(2)
    #=> 2
    instance.instance_variables
    #=> [:@a]
    instance.a
    #=> 2
    

    类实例变量使用示例:

    class A
      @a = 1
      class << self
        attr_accessor :a
      end
    end
    
    A.a
    #=> nil
    A.a = 2
    #=> 2
    A.a
    #=> 2
    instance = A.new
    instance.class.a # access instance's class instance variable
    #=> 2
    

    【讨论】:

    • 感谢您的解释。那么,我可以说继承类中的a 可以通过100 值访问吗?
    • cattr_accessor 是 rails 的一部分,不适合这个问题(没有 rails 标签)
    • @sokkyoku thx,已编辑
    • @emj,对。您可以使用class B &lt; A; endB.a 进行测试
    • 您应该澄清,“类实例无权访问其类的实例变量。”如果@a 是一个值为“dog”的类实例变量并且@b 是一个实例变量,则@b.class.a #=&gt; "dog" 如果@a 有一个读访问器,否则@b.class.instance_variable_get("@a") #=&gt; "dog"
    【解决方案2】:

    实例变量属于对象(又名实例),这就是为什么它们毕竟被称为“实例变量”。

    这里有两个对象:Test,它是Class 的一个实例,a,它是Test 的一个实例。两者都是对象,就像任何其他对象一样。两者都可以像任何其他对象一样具有实例变量。

    两者都有一个名为 @a 的实例变量。 Foo@a 已初始化为 100a@a 根本没有被初始化,未初始化的实例变量评估为 nil

    所以,您的问题是您对正在查看的实例感到困惑。实例变量总是在 self 中查找,在类定义体中,self 是正在定义的类。

    这听起来可能有点迂腐,但我发现了解 Ruby 实际上比人们有时希望你相信的要简单得多,最终会对你有所帮助。

    【讨论】:

      【解决方案3】:

      试试这个:

      class Test
        attr_accessor :a
      
        def initialize
          @a = 100
        end
      end
      
      a = Test.new
      puts a.a
      

      【讨论】:

      • 这不是对“为什么?”问题的解释/回答
      【解决方案4】:

      发生这种情况的原因是这一行:

      @a = 100
      

      分配给一个实例变量,但不是你想的那个。它被分配给Test.a,(测试是Class 的实例)而不是分配给属于Test 的每个实例的实例变量a

      反过来,这一行:

      attr_accessor :a
      

      正在声明一个名为 a 的实例变量的访问器(可通过 Test 的任何实例访问)

      因此你应该有

      class Test
          @a = 100
          class << self
              attr_accessor :a
          end
      end
      puts Test.a #=> will print 100
      

      class Test
          def initialize
              @a = 100
          end
          attr_accessor :a
      end
      a = Test.new
      puts a.a #=> will print 100
      

      这取决于您是只想要一个类常量还是想要一个在每个实例上具有默认值的属性。后者是您的 PHP 代码的直接翻译。

      【讨论】:

      • 如果说那行正在分配一个实例变量会更准确(最终更有帮助)。毕竟,它是一个赋值(=),它是一个实例变量(@)。只是该实例不是 OP 认为的那个实例。它一个实例变量,但是对于错误的实例。
      • 好点,修改了我的答案
      猜你喜欢
      • 2015-03-10
      • 2013-09-21
      • 2012-06-15
      • 1970-01-01
      • 2017-11-30
      • 2017-07-26
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多