为什么Scala编译器拒绝没有前导空格的函数体?

为什么Scala编译器拒绝没有前导空格的函数体?,scala,Scala,我觉得这很令人困惑 scala> val a = (x:Boolean)=>!x <console>:7: error: not found: value x val a = (x:Boolean)=>!x ^ scala> val a = (x:Boolean)=> !x a: Boolean => Boolean = <function1> scala>vala=(x:Boolean

我觉得这很令人困惑

scala> val a = (x:Boolean)=>!x
<console>:7: error: not found: value x
       val a = (x:Boolean)=>!x
                ^

scala> val a = (x:Boolean)=> !x
a: Boolean => Boolean = <function1>
scala>vala=(x:Boolean)=>!x
:7:错误:未找到:值x
val a=(x:Boolean)=>!x
^
scala>vala=(x:Boolean)=>!x
答:布尔=>布尔=

两者之间的唯一区别是空格。是因为lexer认为
=>运算符?

没错,它无法正确解析第一个版本。以下是它为第一个和第二个选项生成的树的差异:

scala> import scala.reflect.runtime.{universe => u}
import scala.reflect.runtime.{universe=>u}

scala> import scala.reflect.runtime.{currentMirror => m}
import scala.reflect.runtime.{currentMirror=>m}

scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> val tb = m.mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@4426fc2e

scala> val treeNotWorking = tb.parse("(x:Boolean)=>!x")
treeNotWorking: tb.u.Tree = (x: Boolean).$eq$greater$bang(x)

scala> val treeWorking = tb.parse("(x:Boolean) => !x")
treeWorking: tb.u.Tree = ((x: Boolean) => x.unary_$bang)
如您所见,它尝试调用
=>x
上执行code>。例如,如果作用域中有
x
,则会出现不同的错误:

scala> val x = true
x: Boolean = true

scala> val a = (x:Boolean)=>!x
<console>:17: error: value =>! is not a member of Boolean
       val a = (x:Boolean)=>!x
scala>val x=true
x:布尔=真
scala>vala=(x:Boolean)=>!x
:17:错误:值=>!不是布尔函数的成员
val a=(x:Boolean)=>!x

Scala不保留符号
=>

scala> val =>! = 42
=>!: Int = 42
该语言未保留的任何连续标点符号字符串都可用于定义。如果要定义同时包含标点符号和字母数字字符的符号,则必须在标点符号和字母数字之间的每个过渡处放置下划线,反之亦然。如果不这样做,则输入字符字符串(如
x+y
)将是单个符号(如在Lisp中)