何时在Ruby中使用常量而不是实例变量?

时间:2015-04-28 18:25:01

标签: ruby variables instance constants

我理解实例变量的意思是状态,而常量意味着不变。是否有任何理由(除了惯例)使用常量而不是实例变量?使用常量是否有内存/速度优势?

3 个答案:

答案 0 :(得分:5)

这里有几点需要考虑:

  • 值会在对象的生命周期内发生变化吗?
  • 您是否需要覆盖子类中的值?
  • 您是否需要在运行时配置值?

最好的常量是那些在更新软件方面没有真正改变的常量:

class ExampleClass
  STATES = %i[
    off
    on
    broken
  ].freeze
end

通常在类中内部使用这些常量并避免共享它们。当你分享它们时,你的使用方式受到限制。例如,如果另一个类引用ExampleClass::STATES,那么您无法在不更改其他代码的情况下更改该结构。

通过提供接口

,您可以使其更加抽象
class ExampleClass
  def self.states
    STATES
  end
end

如果您将来更改该常量的结构,则可以始终保留旧行为:

class ExampleClass
  STATES = {
    on: 'On',
    off: 'Off',
    broken: 'Broken'
  }.freeze

  def self.states
    STATES.keys
  end
end

当您谈论实例变量时,您指的是可以配置的内容:

class ConfigurableClass
  INITIAL_STATE_DEFAULT = :off

  def self.initial_state
    @initial_state || INITIAL_STATE_DEFAULT
  end

  def self.initial_state=(value)
    @initial_state = value ? value.to_sym
  end
end

常量很棒,因为它们被定义一次并在过程的持续时间内使用,所以从技术上来说它们更快。实例变量仍然非常快,并且通常是必需的,如上所示。

答案 1 :(得分:0)

与实例变量不同,常量是全局的。如果你试图重新赋值,他们至少会抱怨。

虽然内存/速度可能存在理论差异,但在实践中却无关紧要。

答案 2 :(得分:0)

你可能没有意识到这一点,但是类和模块被认为是常量。

def function getElement (keys) {
  var el = this.foo

  for (i = 0; i < keys.length; i++) {
    el = el.children[keys[i]]
  }

  return el
}

关于何时应该使用常量,我可以给出的最佳建议是,当它们完全相同时,不变。例如,如果我在rails中创建一个范围来查找所有最近的pry(main)> Foo NameError: uninitialized constant Foo ,我会创建一个显示最近的范围的常量。

Foo