【问题标题】:In what circumstances should I use instance variables instead of other variable types?在什么情况下我应该使用实例变量而不是其他变量类型?
【发布时间】:2011-03-12 07:22:10
【问题描述】:

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

例子:

# Using an instance variable
@accounts = Account.find(...)

# Using a "local"\"normal" variable
account = Account.find(...)

【问题讨论】:

  • 类变量类似于@@accounts@accounts 是一个实例变量。
  • 你给出的第一个例子是一个实例变量,而不是一个类变量。第二个是局部变量。您是特指控制器、模型还是泛指 Ruby 类?
  • @LBg,@Pan Thomakos - 对不起,是我的错误。我不是变数问题的专家。

标签: ruby-on-rails ruby ruby-on-rails-3 class variables


【解决方案1】:

一般来说,实例变量是局部的,并且持久存在于对象的实例中,而局部变量只是局部的,并且持久存在于函数/对象/块范围内。例如:

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 时,您会得到一个 NameError,因为 name 仅被定义为 greet 函数中的局部变量。

@name 对于 User 类的用户实例是本地的。当您尝试在该上下文之外调用它时,您会得到nil。这是局部变量和实例变量之间的区别之一,如果没有定义实例变量,则返回 nil,而局部非实例变量会引发错误。

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

【讨论】:

  • 你能解释一下为什么你会在你的getter方法中使用@name而不是简单的局部变量名吗?既然实例变量和局部变量在它们的上下文中都是有效的,为什么要区分两者呢?
【解决方案2】:

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

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

如果您需要一个变量在函数调用之间持久化,但仅适用于特定的类实例,请将其设为实例变量。

如果您需要在该类的每个实例之间共享的东西,请使用类变量,但是这种需求应该很少见,因此请仔细考虑您是否真的需要类变量.

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

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多