可能重复:
类变量和类实例变量之间的区别?
在阅读 Ruby 书籍时,我似乎错过了变量章节。现在我似乎无法理解以下内容:
- 什么是实例变量?
- 什么是类实例变量?
variable
a和@instance_var
有什么区别@class_instance_var
?
我试图阅读不同博客中的一些帖子,但我仍然不明白。任何帮助,将不胜感激。
可能重复:
类变量和类实例变量之间的区别?
在阅读 Ruby 书籍时,我似乎错过了变量章节。现在我似乎无法理解以下内容:
variable
a和@instance_var
有什么区别@class_instance_var
?我试图阅读不同博客中的一些帖子,但我仍然不明白。任何帮助,将不胜感激。
什么是实例变量?
它是一个具有与该类实例相关的独立值的变量。例如,一个Person
类可以有@name
和@age
作为实例变量。所有的实例Person
都有一个名字和年龄,但是每个实例对于这些东西都有不同的值。
什么是类实例变量?
这有点奇怪,但你必须意识到这个Person
类本身就是Class
. 所以它也可以有实例变量。这通常用于配置类。就像向一个类添加一个 API 密钥,以便可以使用该数据创建所有实例。
class PersonFetcher
# class method can set class instance variables
def self.set_api_key(key)
@api_key = key
end
# instance method sets instance variables
def set_name(name)
@name = name
end
end
变量@instance_var 和@class_instance_var 有什么区别?
它是如何持续存在的。
variable
是本地的。它只是对对象的引用。一旦没有代码或对象引用此值,它就会通过垃圾收集被销毁。只有继续使用它才会持续存在。
@instance_var
持续存在于实例上。只要实例存在,它所拥有的实例变量也会存在。只要Person
实例存在,该实例就会有一个@name
.
@class_instance_var
持续存在于类对象上(记住是 的一个实例Class
)。因此它将永远存在于类对象中,因为您永远无法真正摆脱已声明的类。
网络上有很多规范的解释,在 SO 的其他地方也有一些深入的解释,但我将与您分享另一种看待它的方式:变量范围。
局部变量通常用于方法中,并且仅具有局部范围。例如:
def foo
# bar is only in scope within #foo.
bar = true
end
每当方法返回时,bar变量就会超出范围。
实例变量可用于绑定到对象实例的任何方法。作为一个实际问题,这通常会在某个实例化的类对象中赋予它范围。例如:
class Foo
def bar
@quux = true
end
def baz
@quux == true
end
end
foo = Foo.new
虽然@quux 并不是真正的全局,但它对绑定到我们实例化的foo对象的所有方法都是可见的,而无需将其作为参数显式传递。
类变量在类的所有实例之间共享。这意味着如果您从实例 foo 更改 @@bar,那么实例 bar 的值也会更改。
class Foo
@@bar = true
def show_class_variable
@@bar
end
def bar= value
@@bar = value
end
end
foo = Foo.new
bar = Foo.new
foo.show_class_variable # => true
bar.show_class_variable # => true
foo.bar = false
foo.show_class_variable # => false
bar.show_class_variable # => false
请注意更改 @@bar 如何同时影响两个实例。这就是类变量的美妙之处(也是可怕之处)。
变量是方法的局部变量,因此应该在此方法中定义,实例变量是为给定类的对象(实例)定义的变量,并且每个对象都有一个值。类实例变量用@@
(与您提到的单个变量相反)表示,并在类的所有@
实例之间共享,如果其中一个实例更改其值,则所有实例都将看到新值。类实例变量等价于 c++ 和 java 的静态成员变量,实例变量等价于非静态变量。
实例变量是在类被实例化时定义的。假设你有一个 class Point
,它定义了一些局部变量和方法。
class Point
def initialize(x,y)
@x, @y = x, y
end
def add(other)
Point.new(@x + other, @y + other)
end
end
当您实例化定义的类并将其分配给一个变量时,您正在实例化该类:
point = Point.new(2,2)
..这是实例变量。
Ruby 中的类是对象,并且可以像其他对象一样具有实例变量。在定义内部class
但在实例方法定义外部定义的实例变量称为类实例变量。
例子:
class Point
@n = 0
@total_x = 0
@total_y = 0
def initialize(x,y)
@x,@y = x,y
end
end
还有第三种,即class variable
。类变量对类方法和类的实例方法是可见的,并由其共享。与实例变量一样,类变量可以被类的实现使用,但它们对类的用户是不可见的。类变量以@@
. 实例变量总是参考 评估self
。这与类变量有很大的不同,类变量总是参考由封闭class
定义语句创建的类对象进行评估。使用相同的示例,我们可以重写代码如下:
class Point
@@n = 0
@@total_x = 0
@@total_y = 0
def initialize(x,y)
@x,@y = x, y
@@n += 1
end
def self.report
puts "Number of points: #{@@n.to_s}"
end
end
您可以通过简单的谷歌搜索找到很多文章:
http://blog.codegram.com/2011/4/understanding-class-instance-variables-in-ruby
http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/