根据 Scala 语言规范,包是 AnyRef 值并且具有类型。这有什么意义呢?

2024-01-08

我正在通读 Scala 语言规范,并且遇到了一些令人困惑的事情,即,以下含义:包是值并且它们确实有类型.

以下是我从 Scala 语言规范中得出的这个奇怪事实的结论(也许是错误的?):

背景:

In the 类型指示符 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#type-designators部分,写道:

简单类型 ::= StableId

类型指示符指的是命名值 类型。它可以是简单的或限定的。所有此类类型指示符都是 类型投影的简写。

具体来说,非限定类型名称 t,其中 t 绑定在某些 类、对象或package C被视为C.this.type#t 的简写。 如果 t 未绑定在类、对象或包中,则 t 被视为 ε.type#t 的简写。

合格的类型指示符的形式为 p.t,其中 p 是路径,t 是一个类型名称。这样的类型指示符相当于类型 投影 p.type#t。

下面列出了一些类型指示符及其扩展。我们假设一个局部类型参数 t, a价值维持表具有类型成员 Node 和标准类 scala.Int,

此外,通过考虑类型投影 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#type-projection定义:

SimpleType ::= SimpleType ‘#’ id

A型投影T#x 引用类型 T 的名为 x 的类型成员.

最后,单例类型 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#singleton-types定义说:

SimpleType ::= 路径‘.’类型

单例类型的形式为 p.type, 其中 p 是指向预期符合的值的路径 scala.AnyRef。类型表示由 null 组成的值的集合 和 p 表示的值。

推理链:

所以,我们知道:

1) scala in scala.Int是一个包。

2) scala.Int只是语法糖scala.type#Int(如中所解释的类型指示符定义 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#type-designators并如上图所示)

3) scala.type#Int是类型投影,其中scala.type必须是一个类型类型投影定义 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#type-projection其中指出:

类型投影 T#x 引用类型 T 的名为 x 的类型成员。

4) So scala.type是一种类型!也就是说,它是一个单例类型,根据单例类型的定义 http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#singleton-types,其中说:

单例类型的形式为 p.type,其中 p 是指向的路径 预期符合 scala.AnyRef 的值。

5) scala对应于p这是一个value符合 AnyRef

6)Scala语言规范中here http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#value-types文中写道:

Scala 中的每个值都有一个类型...

7)所以包scala有一个类型。

问题:

1)这个推理正确吗?是否包邮scala真的是符合 AnyRef 的值吗?如果这个推理不正确,请解释原因。

假设上述推理正确并且包scala确实是一个值:

2)包的含义是什么scala一个值 ?这有什么意义呢?在什么背景下我们可以想到scala作为一个值,就像我们想象的那样5:Int是价值5与类型Int?

3)如果包裹scala是一个符合 AnyRef 的值,那么我应该能够将该值放入变量中,我可以这样做吗?如果不能,那为什么不呢?

4) 包裹的价值如何scala在幕后内部(由编译器)表示?它是一个物体吗?该值在运行时是否以 JVM 对象的形式存在?如果是的话,我怎样才能得到它?我怎样才能打电话给toString方法就可以了?


基于实验而不是规范:

1) 包有类型但它们符合Any, not AnyRef。您不能将它们分配给types:

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 types:

scala> type q = Int
defined type alias q

我怀疑发生了其他事情

2)我怀疑这是在规范中的唯一原因是支持package objects。如果我们写

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在某种意义上“存在”,但无法在源中命名它(除了包对象本身)?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据 Scala 语言规范,包是 AnyRef 值并且具有类型。这有什么意义呢? 的相关文章

随机推荐