Scala:两个下划线后面跟着冒号,解析为一个令牌



我最近在玩Play的JSON库,并注意到这不能编译:

val steps = Seq("a", "b", "c")
steps.foldLeft(__)((a, x) => a  x)

经过一些修改和浏览源代码后,我找到了正确的表达式:

steps.foldLeft(JsPath())((a, x) => a  x)

甚至:

steps.foldLeft(__())((a, x) => a  x)

…虽然第二个看起来很混乱。

后来我发现了一个更有效、更简洁的表达方式:

JsPath(steps.toList map KeyPathNode)

但我不断回到原来的表达和玩弄它。我发现这是有效的:

steps.foldLeft(JsPath: JsPath)((a, x) => a  x)

不知何故,这不是:

steps.foldLeft(__: JsPath)((a, x) => a  x)

得到error: not found: value __。但是,这是可行的:

steps.foldLeft((__): JsPath)((a, x) => a  x)

steps.foldLeft({__}: JsPath)((a, x) => a  x)

:

steps.foldLeft(__.asInstanceOf[JsPath])((a, x) => a  x)

为什么带__: JsPath的表达式失败了?

…就在我准备提交这个问题之前,我发现了另一个有效的表达:

steps.foldLeft(__ : JsPath)((a, x) => a  x)

似乎解析器将__:解释为一个令牌。但它为什么会这样做呢?我认为下划线只是另一个有效的标识符字符。是否有一些特殊情况的解析规则在起作用?

下划线在标识符中是特殊的,因为它可以后跟操作符,包括::例如foo_+是一个标识符,其中foo+是两个令牌:foo +

首先,标识符可以以字母开头,后面可以是任意的字母和数字序列。可以后跟下划线_字符和另一个由字母和数字或操作符字符组成的字符串。

注意,在第一个句子中,_$被认为是大写字母。所以__:是合法的标识符,但_:不是。

相关内容

最新更新