Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
@variable在Ruby中是什么意思?_Ruby_Syntax_Instance Variables_Class Variables - Fatal编程技术网

@variable在Ruby中是什么意思?

@variable在Ruby中是什么意思?,ruby,syntax,instance-variables,class-variables,Ruby,Syntax,Instance Variables,Class Variables,什么是前面带有双at符号(@)的Ruby变量?我对前面带有at符号的变量的理解是,它是一个实例变量,在PHP中是这样的: PHP版本 class Person { public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } }

什么是前面带有双at符号(
@
)的Ruby变量?我对前面带有at符号的变量的理解是,它是一个实例变量,在PHP中是这样的:

PHP版本

class Person {

    public $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}
红宝石当量

class Person

    def set_name(name)
        @name = name
    end

    def get_name()
        @name
    end
end

双at符号
@
是什么意思?它与单at符号有何不同?

@
表示类变量,即它可以继承


这意味着,如果您创建该类的子类,它将继承该变量。因此,如果您有一个class
Vehicle
带有class变量
@@number\u of_wheels
,那么如果您创建一个class
Car
,那么它也会有class变量
@@number\u of_wheels

一个前缀为
@
的变量是一个实例变量,而前缀为
@
的是类变量。看看下面的例子;其输出在
puts
行末尾的注释中:

class Test
  @@shared = 1

  def value
    @@shared
  end

  def value=(value)
    @@shared = value
  end
end

class AnotherTest < Test; end

t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2

x = Test.new
puts "x.value is #{x.value}" # 2

a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3
我包括了
Square
示例(输出
nil
),以证明这可能不会像您预期的那样100%地表现出来;在这个问题上,政府有很多额外的信息


此外,请记住,与大多数数据一样,根据dmarkow的评论,您应该非常小心地使用类中的类变量。

@
-类的实例变量
@
-类变量,在某些情况下也称为静态变量

类变量是在类的所有实例之间共享的变量。这意味着从这个类实例化的所有对象只存在一个变量值。如果一个对象实例更改了变量的值,那么对于所有其他对象实例,该新值实际上都会更改

另一种思考类变量的方式是在单个类的上下文中作为全局变量。
类变量是通过在变量名前面加上两个
@
字符(
@
)来声明的。类变量必须在创建时初始化,当类扩展或包含模块时,模块中的@也会以不同方式工作

如此给定

module A
    @a = 'module'
    @@a = 'module'

    def get1
        @a          
    end     

    def get2
        @@a         
    end     

    def set1(a) 
        @a = a      
    end     

    def set2(a) 
        @@a = a     
    end     

    def self.set1(a)
        @a = a      
    end     

    def self.set2(a)
        @@a = a     
    end     
end 
然后,您会得到下面显示为注释的输出

class X
    extend A

    puts get1.inspect # nil
    puts get2.inspect # "module"

    @a = 'class' 
    @@a = 'class' 

    puts get1.inspect # "class"
    puts get2.inspect # "module"

    set1('set')
    set2('set')

    puts get1.inspect # "set" 
    puts get2.inspect # "set" 

    A.set1('sset')
    A.set2('sset')

    puts get1.inspect # "set" 
    puts get2.inspect # "sset"
end 

class Y
    include A

    def doit
        puts get1.inspect # nil
        puts get2.inspect # "module"

        @a = 'class'
        @@a = 'class'

        puts get1.inspect # "class"
        puts get2.inspect # "class"

        set1('set')
        set2('set')

        puts get1.inspect # "set"
        puts get2.inspect # "set"

        A.set1('sset')
        A.set2('sset')

        puts get1.inspect # "set"
        puts get2.inspect # "sset"
    end
end

Y.new.doit

因此,在模块中使用@作为所有用途的通用变量,在模块中使用@作为每个用途上下文的独立变量。

答案部分正确,因为@实际上是每个类层次结构的类变量,意味着它由一个类共享,它的实例及其子类及其实例

class Person
  @@people = []

  def initialize
    @@people << self
  end

  def self.people
    @@people
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Student.new

puts Graduate.people
班级人员
@@人=[]
def初始化

@@我不认识的人,但我感觉它在盯着我。我现在有点害怕用Ruby编写代码…TL;公共灾难恢复:100次中有99次,我会在
self
方法中使用“类实例”变量(
@
),而不是类变量(
@
)。请参阅下面答案中的一系列原因。这意味着,如果您创建该类的子类,它将继承该变量。因此,如果您有一个类
车辆
和一个类变量
车轮数量
,那么如果您创建一个
类车辆
,那么它也将有一个类变量
@@number of of of the wheels
,如果我有一个
类车辆
@number of the wheels
,然后
class Car
还将有一个名为
@number\u of_wheels
的实例变量。类变量的关键区别在于类具有相同的变量,例如,改变一个会改变另一个。如果您包含代码,说明如何在类级别使用实例变量来跟踪类级别的数据,而不出现子类之间共享数据的“奇怪”行为,那么这个答案将是完美的。我还想指出,在多线程环境中,类变量可能是危险的/不可靠的(例如Rails)嗯……在某种程度上,它听起来像PHP中的静态变量,但继承部分是不同的。我不认为PHP有与此完全相同的东西。我不明白对于那些对
类感到困惑的人来说,
ruby类有什么不正确的地方。@myvariable从来不是“该类所有实例的单一共享变量”。它是仅具有该对象作用域的一个对象的实例变量。如果该对象不提供该变量的访问器,则其他对象(即使是声明该变量的类的实例)将无权访问该变量。这种情况实际上与访问实例的能力没有区别属于任何其他对象的变量。
class Person
  @@people = []

  def initialize
    @@people << self
  end

  def self.people
    @@people
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Student.new

puts Graduate.people
#<Person:0x007fa70fa24870>
#<Student:0x007fa70fa24848>
class Person

  def initialize
    self.class.add_person self
  end

  def self.people
    @people
  end

  def self.add_person instance
    @people ||= []
    @people << instance
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Person.new
Student.new
Student.new
Graduate.new
Graduate.new

puts Student.people.join(",")
puts Person.people.join(",")
puts Graduate.people.join(",")
#<Student:0x007f8e9d2267e8>,#<Student:0x007f8e9d21ff38>
#<Person:0x007f8e9d226158>,#<Person:0x007f8e9d226608>
#<Graduate:0x007f8e9d21fec0>,#<Graduate:0x007f8e9d21fdf8>