Scala:两个下划线后跟冒号解析为一个标记

标签 scala playframework

我最近在玩 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)

我收到错误:未找到:值__。然而,这有效:

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

这也有效:

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

还有这个:

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

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

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

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

解析器似乎将 __: 解释为一个标记。但它为什么要这么做呢?我认为下划线只是另一个有效的标识符字符。是否有一些特殊情况的解析规则负责?

最佳答案

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

First, an identifier can start with a letter which can be followed by an arbitrary sequence of letters and digits. This may be followed by underscore _ characters and another string composed of either letters and digits or of operator characters.

请注意,对于此处第一句的目的,_$ 被视为大写字母。因此 __: 是合法标识符,但 _: 不是。

关于Scala:两个下划线后跟冒号解析为一个标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086867/

相关文章:

scala - 为什么可以在 REPL 中声明同名变量?

scala - 如何克隆案例类实例并仅更改 Scala 中的一个字段?

scala - 升级在 Lift Framework 上运行的应用程序?

java - Play Framework 2-3 天后停止响应

scala - Play Framework 双向支持,包括旧版浏览器

java - 玩框架Twitter4J库

scala - 加入多个rdd

scala - Spark DataFrame 已弃用的 java.sql.Date 的替代方案

heroku - SQLException : Timed out waiting for a free available connection

安全登录后尝试访问任何页面时发生 JPA 异常