【问题标题】:Assignment to constant within body of method分配给方法体内的常量
【发布时间】:2016-06-01 03:02:50
【问题描述】:

David Flanagan 和 Yukihiro Matsumoto 所著的“Ruby 编程语言”在第 4.5.2 节分配给常量中陈述了以下内容

在方法体中不允许给常量赋值。

我理解了前提并尝试了两种代码变体:

PERSONS = {}

def create_persons(filename)
  File.foreach(filename).with_index do |line, number|
    array = line.split(' ').unshift(number+1)
    hash = {:id => array[0],:first_name => array[1], :last_name => array[2], :email => array[3]}
    PERSONS = hash
  end
end

我收到一个错误:

santa.rb:13: dynamic constant assignment
    PERSONS = hash
             ^

我尝试了第二个版本,我没有使用等于运算符进行分配,而是将一个空数组初始化为常量,并使用附加运算符将哈希附加到空数组。这行得通!

PERSONS = []

def create_persons(filename)
  File.foreach(filename).with_index do |line, number|
    array = line.split(' ').unshift(number+1)
    hash = {:id => array[0],:first_name => array[1], :last_name => array[2], :email => array[3]}
    PERSONS << hash
  end
end

我的问题是为什么当我使用

【问题讨论】:

  • 为什么不呢?您没有分配或重新定义常量-您正在对该常量引用的对象执行某些操作。 Nitpick:&lt;&lt; 不是任何形式的任务,而是一种方法。
  • @dave-newton >= y (x = x >> y)。这增加了我的困惑。
  • 好的,@DaveNewton。我现在得到您的评论,并了解分配(更改对象引用)和修改常量引用的对象(引用是同一个对象,但已修改)之间的区别。谢谢。

标签: ruby constants


【解决方案1】:

关于 Ruby 中常量的奇怪之处在于,您可以定义一次它们,但除非它们被冻结,否则可以无休止地修改它们。第一个是一个问题,因为您正在切换 PERSONS 所指的对象。在第二种情况下,您正在向现有对象添加内容,这是允许的。

从技术上讲,可以重新定义常量,但最好避免这样做。

【讨论】:

  • 我不会说这很奇怪。我认为大多数或至少许多具有可变对象的 OOP-ish 语言的行为相似。
  • 与其他语言的const 相比。它们在 Ruby 中几乎不是“恒定的”!
  • 这就是我的意思。除了 Ruby 非常奇怪的重新分配常量的能力之外,它的常量的行为非常类似于用 const 指向 C++ 或 Objective-C 对象的变量,或者在 Java 中使用 final,在 C# 中使用 readonly,@987654326 Swift 中的 @(用于引用类型,即类但不是结构),或 JavaScript 中的 const
  • 在 C++ 中,const 推断出 immutabilitypermanence 虽然有可能有一个 const 指向非const 的指针事物。通常const 是对编译器的提示,可以假设该值不会改变。在 Ruby 中,您根本无法保证不变性,至于永久性,嗯,使某物成为常数更像是一种承诺,以后可以提醒。
  • @tadman:我认为你的回答有点误导,因为有些草率(我试图想出一个更好、更中性的词,但作为一个非本地人,没有什么可以想到的,抱歉)在措辞中:a)他修改常量,他正在修改常量引用的对象,并且b)你不能冻结常量,只能冻结对象.
猜你喜欢
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多