[英]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.