【问题标题】:Why does Scala support shadow variables? [closed]为什么 Scala 支持影子变量? [关闭]
【发布时间】:2011-10-25 06:10:48
【问题描述】:

我认为使用影子变量太危险了。为什么 Scala 支持这种语言结构?应该有一些强有力的理由,但我找不到。

【问题讨论】:

  • 我也想知道同样的事情。也许 Odersky 等人只是将这种行为从 Java 中转移出来而没有考虑。
  • 我相信奥德斯基先生对任何特定语言结构的决策都有一定的动机。 :)
  • :) 很公平。我猜他认为编译器警告就足够了。我可以看到 scalac 采用编译器选项 -Ywarn-shadowing,所以大概 IDE 也支持它。
  • @amir75 实际上,所有 -Y 都是 Paul Phillips 的作品,在本质上有点实验性质。如果它在那里,那是因为它实际上对他很有用,很可能。
  • 我看到它已经过时了,但是......这是我最近读过的最奇怪的问题。什么是替代方案?一个巨大的全球范围,每个导入的图书馆都会受到严重污染?奇怪的变量和函数名称,例如 glDrawStuff 或 cvSeeStuff?

标签: scala language-construct


【解决方案1】:

提醒一下:当一个变量、方法或类型在内部范围内声明时,它会遮蔽另一个同名的变量、方法或类型,因此不可能以非限定的方式(或者,有时,完全)引用外部范围的实体。 Scala 和 Java 一样,允许阴影。

我可以看到的一个可能原因是,在 Scala 中,经常有许多嵌套范围,每个范围都相对较短(与 Java 或 C++ 相比)。事实上,一个块可以在任何需要表达式的地方开始,从而开始一个新的范围。因此,平均而言,在内部作用域中使用阴影名称更接近于它们的声明并且不那么含糊。

此外,内联闭包通常会导致程序员在已经很拥挤的范围内需要新的变量名。允许阴影还允许继续使用足够中肯的描述性名称,即使它们与已经使用的名称相同,而不是发明其他奇怪的名称——比如在它们前面加上mylocal,或者(更糟) _ 或单字母名称...

对于好的 IDE,阴影不再是一个问题,例如在源代码中突出显示光标下变量的声明和引用。

这里只有我的两分钱……

【讨论】:

  • 感谢您的详细回复和我未提供的提醒。我想到了闭包上下文中的变量阴影。没错,一些开发人员可能会在闭包的范围内使用相同的名称,而不是提供一些新名称。我猜这些开发人员只是觉得使用起来更舒服。但这不是隐藏的威胁吗?我同意短范围变量名称的前缀看起来并不完美。但它使代码在大多数情况下更容易理解(尤其是对于 Scala 新手)。如果我错了,请纠正我。
【解决方案2】:

我认为使用影子变量太危险了。

你有权想任何你想的。但是,由于您没有提供数据、研究甚至理由,因此该意见没有任何价值。

为什么 Scala 支持这种语言结构?

因为它有用。程序员不需要仅仅因为作用域中的某些标识符已经在使用它就可以发明任意标识符名称。

它还使通配符导入更加有用,因为它消除了仅仅因为第三方添加了您正在使用的标识符而导致编译中断的可能性。

这应该有一些强有力的理由,但我找不到。

为什么要有充分的理由呢?它有优点,没有缺点(你没有提出),这就足够了。

编辑

在回答所解释的缺点时,我必须说这是阴影的一种特殊情况。阴影还会影响导入中的所有内容,无论是通过import 语句还是通过嵌套的package 语句,以及同一包中的所有内容。

让我们看一些例子:

// Not allowed, because it shadows List
import java.util._ 

class A {
    // Not allowed, because it shadows this, hashCode, equals, toString
    class B
}

那会是一种非常烦人的语言。

【讨论】:

  • 影子变量的危险太明显了,无法在最初的问题中描述。顺便说一句,我已经在对 Jean-Philippe 的回答的评论中写过它(可能你还没有读过它)。但我会特别为你重复。
  • 当某人在某个范围内声明一个变量并且该变量与外部范围内的另一个变量具有相同的名称时,他或她会使代码更加复杂。跟踪每个变量的含义要困难得多。下面是来自“Scala 编程”的一段很好的引用:“请记住,这样的代码可能会让读者非常困惑,因为变量名在嵌套范围内采用了新的含义。通常最好选择一个新的、有意义的变量名,而不是遮蔽外部变量。”
  • @keykeeper 好的,我回答了这个论点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 2011-01-17
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多