在为数字文字赋值时,Scala不会出现编译时错误?

cub*_*uce 8 scala runtime-error

在学习的过程中scala我偶然发现了以下奇怪的片段:

package temptests

object TempTest {
  //def 2 = 123 // does not compile
  val 2 = 123 // compiles, but leads to an exception at runtime

  def main(args: Array[String]) = { // just do something to load this class
    println("Hello")
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望编译器会抛出错误,val 2 = 123因为标识符不能以数字开头,但代码编译时没有警告.但是,在运行时它会立即抛出异常:

异常线程 "main" java.lang.ExceptionInInitializerError在temptests.TempTest.main(TempTest.scala)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at com.intellij.rt.execution.application.AppMain.main(AppMain.java: 144)引起:scala.MatchError:123(类java.lang.Integer)temptests.TempTest $.(TempTest.scala:5)temptests.TempTest $.(TempTest.scala)... 6更多

我只是好奇:怎么val 2 = 123理解Scala?为什么没有编译时错误?

Yuv*_*kov 12

我只是很好奇:val 2 = 123Scala 如何理解?

您可以将其val 2 = 123视为:

123 match {
    case 2 => 2
}
Run Code Online (Sandbox Code Playgroud)

Scala中的变量名称部分并不总是简单的名称,它也可以是模式,例如:

val (x, y) = (1, 2)
Run Code Online (Sandbox Code Playgroud)

将1和2分别分解为x和y.在scala中,在val之后也允许在case语句之后允许的所有内容并将其转换为模式匹配.

从规范(强调我的):

或者,值定义可以具有左侧的模式.如果p是除简单名称或名称后跟冒号和类型之外的某种模式,则值定义val p = e扩展如下:

(跳到相关示例):

如果p具有唯一的绑定变量x:

val x = e match { case p => x }
Run Code Online (Sandbox Code Playgroud)

这是编译器不发出编译时错误的原因.在这个谷歌小组问题中对这个主题进行了长时间的讨论.

  • 我也不是,但如果确实没有用例,那么如果编译器会在左侧捕获文字的特殊情况会更好,因为它不会有任何意义并且可能是错字.但这实际上只是一个小问题,而我只对了解"为什么"感兴趣. (3认同)