为什么人们使用_?作为标识符后缀?

Saw*_*yer 14 scala lift

我开始阅读Lift框架源代码,我发现有很多方法使用名称定义methodName_?,是否有一个_?具有一些特殊含义的约定?

def empty_? : Boolean = {}
Run Code Online (Sandbox Code Playgroud)

Kev*_*ght 26

您不太可能在升降机框架外看到构造; 我怀疑它主要是Ruby嫉妒.

几乎任何其他Scala项目都会回避这种语法.不是因为尾随问号,而是因为它是将下划线引入代码的另一种方式 - 并且符号已经过度重载.

基于对多个Scala项目的评估,该符号可以合理地描述为非惯用的.

UPDATE

需要下划线的原因是消除中缀符号的歧义,其中:

x?y
Run Code Online (Sandbox Code Playgroud)

会被解读为

x.?(y)
Run Code Online (Sandbox Code Playgroud)

?作为一个方法名.鉴于:

x_?y
Run Code Online (Sandbox Code Playgroud)

显然x_?是原子的说法.

语法是正式称为"混合标识符"的示例,旨在允许诸如的定义

def prop_=(v:String) = ... //setter
def unary_- = ... //prefix negation operator
Run Code Online (Sandbox Code Playgroud)

当类似的构造仅仅用于在方法名称的末尾推送问号时,它可以(可以说)被认为是一种黑客攻击.

  • 这个答案的主要+1.我打算发布类似的东西,但你打败了我.通常,Lift(和相关模块)是唯一使用此约定的Scala框架.它还为"危险"方法使用`_!`后缀(例如`box`上的`open_!`).通常,在Scala中不鼓励使用混合的alpha符号标识符,但mutator上的`_ =`除外.除了`_?`之外,你应该使用`is ...`的Java约定,除了原始属性,它应该只是属性名称(例如`visible`,而不是`isVisible`). (6认同)
  • "这个符号已经过度重载"作为一个单独的标记,当然,但不是标识符内部. (3认同)
  • @Alexey Romanov:尽管如此,这违反了在标识符中使用CamelCase和dromedaryCase的Scala惯例. (3认同)
  • @larsmans这首先反映了将复合标识符放入Scala的全部原因! (2认同)
  • 很清楚地说"没有与method_相关的糖,与method_ =不相符". (2认同)

Fre*_*Foo 25

?表示,这是一个谓词,函数返回Boolean.这个约定可以追溯到Lisp,其中?(Scheme)p-p(其他Lisps,模拟带有"类似"字母的问号)也表示谓词.把它想象成一个问题,"对象是空的吗?"

如果您将它们分开,Scala将只允许混合标识符名称(包含字母数字和标点符号)_.例如,

scala> def iszero?(x : Int) = x == 0 
<console>:1: error: '=' expected but identifier found.
       def iszero?(x : Int) = x == 0
                 ^
Run Code Online (Sandbox Code Playgroud)

不起作用,但是

scala> def iszero_?(x : Int) = x == 0          
iszero_$qmark: (x: Int)Boolean
Run Code Online (Sandbox Code Playgroud)

确实.