我最近在玩 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
+
。
请注意,对于此处第一句的目的,_
和 $
被视为大写字母。因此 __:
是合法标识符,但 _:
不是。
关于Scala:两个下划线后跟冒号解析为一个标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086867/