我正在阅读Scala语言规范,我遇到了一些令人困惑的事情,即暗示包是值,而且它们有类型。
以下是我从Scala语言规范中得出的结论(可能不正确?)这个奇怪的事实:
背景
在type designators部分,写着:
SimpleType :: = StableId
类型指示符指的是命名值 类型。它可以是简单的或合格的。所有这些类型的指示符都是 类型预测的缩写。
具体来说,非限定类型名称t其中t绑定在某些中 class,object或 package C 被视为C.this.type #t 的简写。 如果t未绑定在类,对象或包中,则t被视为a ε.type#t的简写。
合格的类型指示符的形式为p.t,其中p是路径和t 是一个类型名称。这种类型的指示符等同于类型 投影p.type #t。
下面列出了一些类型标识符及其扩展名。我们假设一个局部类型参数t,一个值可维护,带有一个类型成员Node和标准类scala.Int,
此外,通过考虑type projection定义:
SimpleType :: = SimpleType'#'id
类型投影 T#x引用类型为T的类型成员T 。
最后,singleton type定义说:
SimpleType :: = Path'。'type
单例类型的形式为p.type, 其中p是指向期望符合的值的路径 scala.AnyRef。该类型表示由null组成的值集 和p。
表示的值
推理链:
所以,我们知道:
1)scala
中的scala.Int
是一个包。
2)scala.Int
只是scala.type#Int
的语法糖(如type designator definition中所述,如上图所示)
3)scala.type#Int
是一种类型投影,其中scala.type
必须是符合the type projection definition的类型:
类型投影T#x引用类型为T的类型成员。
4)所以 scala.type
是一种类型!也就是说,它是单身类型,根据definition of singleton types,它说:
单例类型的形式为p.type,其中p是指向的路径 一个符合scala.AnyRef的值。
5)scala
对应p
,这是符合AnyRef的值
6)在Scala语言规范here中写道:
Scala中的每个值都有一个类型......
7)所以包scala
有一个类型。
问题:
1)这个推理是否正确?包scala
真的是一个符合AnyRef的值吗?如果这种推理不正确,请解释原因。
假设上述推理是正确的并且包scala
确实是一个值:
2)包scala
在什么意义上是一个值?这怎么有意义呢?在什么情况下,我们可以将scala
视为一个值,就像我们认为5:Int
是5
类型Int
的价值一样?
3)如果包scala
是一个符合AnyRef的值,那么我应该能够将该值放入变量中,我可以这样做,如果没有,那么为什么不呢?
4)包scala
的值是如何在幕后内部(由编译器)表示的?它是一个对象吗?此值是否以JVM对象的形式存在于运行时?如果是的话,我怎么能抓住它呢?如何在其上调用toString
方法?
答案 0 :(得分:5)
基于实验而不是规范:
1)包有类型,但它们符合Any
,而不是AnyRef
。您无法将其分配给type
s:
scala> type t = java.type
<console>:7: error: type mismatch;
found : java.type
required: AnyRef
Note that java extends Any, not AnyRef.
Such types can participate in value classes, but instances
cannot appear in singleton types or in reference comparisons.
有趣的是,这不是对Any
类型的一般限制:
scala> type q = Int
defined type alias q
我怀疑其他事情正在发生
2)我怀疑这个规范的唯一原因是支持package object
。如果我们写
package object foo {
val x = 5
val y = this
}
那么说foo
不是一个值(特别奇怪的是y
不是一个值)会很奇怪。如果一个普通的软件包在我们为它定义package object
后立即疯狂地发布了一个值,那也会很奇怪。
3)我无法看到任何方法,因为我无法看到任何方式来访问该值。该错误甚至表示包不是值:
val f = foo
test.scala:10: package foo is not a value
值foo
&#34;可能存在&#34;从某种意义上说,但是没有办法在源代码中命名它(在包对象本身中除外)?