繁体   English   中英

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

[英]Scala gives no compile-time error when assigning a value to a number literal?

在学习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")
  }
}

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

在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at的sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)的temptests.TempTest.main(TempTest.scala)中的线程“main”java.lang.ExceptionInInitializerError中的异常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更多

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

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

您可以将val 2 = 123视为:

123 match {
    case 2 => 2
}

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

val (x, y) = (1, 2)

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

从规范 (强调我的):

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

(跳到相关示例):

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

val x = e match { case p => x }

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

val声明的左侧可以是模式。 请参阅scala语言文档

所以

val 2 = 123

可写成

123 match {
  case 2 => 2
}

这给出了匹配错误。

在现实生活中,这主要用于将元组提取到可读的本地vals:

val test = ("Foo", 30)
val (name, age) = test

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM