在什么情况下我应该使用实例变量而不是其他变量类型?

我正在使用Ruby on Rails 3,我想知道在什么情况下我应该使用实例变量而不是其他变量类型,如果有安全原因那些。

例:

# Using an instance variable @accounts = Account.find(...) # Using a "local"\"normal" variable account = Account.find(...) 

通常,实例变量是本地的并且持久存储在对象的实例中,而局部变量只是本地变量并且持久存储在函数/对象/块范围内。 例如:

 class User def name @name end def name= name @name = name end end def greet user name = user.name || 'John' p "Hi, my name is #{name}" end user = User.new greet user => 'Hi, my name is John' name => NameError: undefined local variable or method 'name' for main:Object user.name = "Mike" greet user => 'Hi, my name is Mike' @name => nil 

在greet函数中, name是一个仅在该函数中定义的局部变量。 name变量在函数的第一行设置, name = user.name || 'John' name = user.name || 'John' ,但它的值不会在函数之外持久存在。 当您尝试调用name您会收到NameError因为name只被定义为greet函数中的局部变量。

@name是User类的用户实例的本地。 当你尝试在该上下文之外调用它时,你会得到nil 。 这是本地变量和实例变量之间的一个区别,如果尚未定义实例变量,则返回nil,而本地非实例变量会引发Error。

请注意,两个变量类型都是特定上下文的本地变量。 @name是在用户实例中定义的,因此当您调用user.name时,您将在用户实例中调用name函数,其中定义了@namename仅在greet函数中定义,因此当您调用p "Hi, my name is #{name}"您可以获取name的值,因为您在其定义范围内。

@Pan的回答很好地解释了它们之间的区别。

通常(几乎任何语言)您都希望在所需的最小范围内定义变量。 因此,如果您不需要在函数调用之间保留某些内容,请将其设置为本地。

如果需要跨函数调用持久化变量,但仅针对特定类实例,请将其设为实例变量。

如果你需要在该类的每个实例之间共享的东西,那么使用类变量,但是对此的需求应该有点罕见,所以仔细考虑你是否真的需要一个类变量。

(免责声明:我只使用Ruby大约2周,所以这主要是语言无关的答案,但我很确定它适用于Ruby。如果我错了,请随意纠正我。)