Scala在名称中加下划线

问题描述:

我已阅读了多个样式指南和其他资源,指出在方法/变量/其他名称中使用下划线是一个坏主意。Scala在名称中加下划线

背后有什么技术原因?

我非常习惯于用_预先设定帮助功能。还有一些功能应该是我想要公开的私人功能,所以我可以通过REPL访问它们。其他命名约定像使用“助手”后缀似乎很麻烦。

任何想法,将不胜感激!

通配符运算符_在Scala中被大量使用。所以:

xs map (_.x) // Call the x method of every element 
xs map (_x) // Pass every element through the _x method 

令人困惑。你必须仔细看看下划线是否在前。

然而,内部下划线更难迷惑:

xs map (my_method) // No similar form where _ stands for the list element 

因此,这些都是问题较少,但下划线仍然吸引眼球一点,当一个正在寻找倒闭。这可能是为什么他们不鼓励,但说实话,我一直都在使用它们,特别是在隐式defs和内部变量等事物中,他们在界面中没有太多或任何暴露。

+3

这是一个非常构建的案例:你有一个'xs:Seq [T:{def x:U}]'。为了发生错误,你需要一个'_x:{def apply(y:T):U}'。如果这三个约束中的任何一个都不存在,它就不会编译。它必须被正确命名为'_x',必须用一个'T'参数来调用,它必须返回一个'U'。我甚至没有轻信。 –

+3

@放羊 - 你不可能有这种名字相撞;重点在于,当您通过仅仅是熟悉的代码快速阅读时,您不会立即知道本地代码中的私有方法还是集合元素上的公共方法正在播放。当然,你可以很快弄清楚,但如果你能从远处看出形状,你可以更快地找出答案。 –

我认为这些规格只是强调名称。

以什么(理智)的方式,你应该写下面的,如果不是这样?

object getterSetter { 
    var _variable: Option[Double] = None 
    def variable = _variable 
    def variable_=(newVal: Double) { _variable = Some(newVal) } 
} 

我认为camelCase,而不是embedded_underscores的原因很简单,Java使用的是与Java库工作时,一致性只能保持这样。

+2

下划线的前缀是_convention_;你仍然必须声明它是私人的。此外,你可以使用'variableHidden'或其他任何数量的东西来代替'_variable'。 –

+0

哦,你是对的。一定有这个困惑。但'variableHidden'?当真? –

+0

我也使用'_variable',但Rex Kerr的答案中的参数很有趣。 –

我只知道我避免在名称中强调的原因:它们是Scala语法的重要组成部分,它们遍布整个地方。当然,你可以可以用来表示名字,但是在我的经验中,它往往会减慢人类语法分析器的速度。

但我必须承认,我偶尔会在可变对象中为私有变量使用下划线前缀,如果我想公开方法的非下划线名称。如果我们可以使用像Haskell这样的素数(foo')会很好,但是我认为这在词汇上会很困难。

除了在整个语言中使用_,不仅仅是作为通配符使用,还作为公用API的一部分(如元组)(someTuple._1等),它在某些情况下也由编译器特别解释。例如在设置器,其必须后缀_=或在一元运营商,其中必须加上前缀unary_

当有人使用类似但不完全相同的“特殊名称”时,所有这些都使得使用“特殊名称”非常容易,或者错误地解释了“普通名称”。不管它是偶然发生还是缺乏知识都没关系,但是当它发生时,你可能会花几个小时寻找一个bug。所以不要使用它们,除非你真的必须这样做。DSL一如既往例外。