我开始阅读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)
当类似的构造仅仅用于在方法名称的末尾推送问号时,它可以(可以说)被认为是一种黑客攻击.
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)
确实.