2

我还在学习 Ruby,我很好奇在这种情况下使用类变量、常量还是局部变量是否合适。

在我下面的代码示例(从固定字符集中生成随机用户名)中,分配@username为实例变量是相当明显的。但我很好奇我应该将字符集分配为常量还是类变量。在这种情况下使用另一种变量类型有什么好处?

在当前示例中,_charset在每个实例中计算 。(如果我的假设是错误的,请纠正我。)我还假设计算将在实例之间共享(而不是重新计算)作为类变量和常量?

class NewAccount

  def initialize
    @username = self.generate_username
  end

  def generate_username
    _charset = ('a'..'z').to_a + ('0'..'9').to_a
    _newusername = Array.new(20) { _charset[rand(_charset.length)] }.join
    return _newusername
  end

end
4

4 回答 4

3

您可以将其设为类变量或常量,实际上这将是相同的:只存在一个实例。并且 Ruby 常量并不是真正的常量——你可以改变一个常量,所以它实际上是一个变量,只是因为它的名字 Ruby 识别一个常量,如果你试图改变它就会发出警告。

但是通过将其声明为常量而不是类变量,您正在记录您的目标:拥有一个由字符集组成的常量值,该值不是为了更改而设计的。这对于任何阅读代码的人来说都是显而易见的。这就是您想要的字符集 - 这样做。

如果你把它变成一个类变量,它将是一个变量:所以如果有人试图改变也没问题。当然,如果您出于某种原因计划更改其值,请使用类变量:再次记录您的设计。

于 2011-04-30T20:15:49.693 回答
2

因为_charset = ('a'..'z').to_a + ('0'..'9').to_a从不改变它的定义,所以我将它创建为一个类常量:

class NewAccount

  CHARSET = ('a'..'z').to_a + ('0'..'9').to_a

  def initialize
    @username = self.generate_username
  end

  def generate_username
    _newusername = Array.new(20) { CHARSET[rand(CHARSET.length)] }.join
    return _newusername
  end

end
于 2011-04-30T21:38:57.077 回答
1

我认为您可以将其设为类变量,因为 _charset 将仅在 NewAccount 类中使用,并且它的值不会因 NewAccount 的实例而改变。

于 2011-04-30T20:03:19.670 回答
1

在您的示例中,@username 将为每个实例计算一次,而 _charset 在您的示例中仅计算一次 - 但 _charset 只是一个局部变量,因此如果您运行该方法两次,它将被重新计算。

您想要的是Tin Man建议的内容,将其设置为常数并计算一次。使用类变量 (@@charset) 可能会产生误导,因为字符集在任何时候都不会改变。

于 2011-05-01T14:20:59.000 回答