在 GitHub 上编辑此页面

已弃用:包对象

包对象

package object p {
  val a = ...
  def b = ...
}

将被删除。它们仍然可用,但将在将来的某个时间点被弃用并删除。

由于现在可以在顶层编写所有类型的定义,因此不再需要包对象。示例

package p
type Labelled[T] = (String, T)
val a: Labelled[Int] = ("count", 1)
def b = a._2

case class C()

extension (x: C) def pair(y: C) = (x, y)

一个包中可能有多个源文件包含此类顶层定义,并且源文件可以自由地将顶层值、方法和类型定义与类和对象混合使用。

编译器会生成合成对象来包装属于以下类别的顶级定义:

  • 所有模式、值、方法和类型定义,
  • 隐式类和对象,
  • 不透明类型别名的伴生对象。

如果源文件 `src.scala` 包含这样的顶级定义,它们将被放入名为 `src$package` 的合成对象中。然而,这种包装是透明的。`src` 中的定义仍然可以作为封闭包的成员访问。合成对象将被放置在文件的最后,位于任何其他包语句、导入语句或对象和类定义之后。

**注意:**这意味着

  1. 包含包装的顶级定义的源文件名与二进制兼容性相关。如果文件名更改,生成的合成对象及其类的名称也会更改。

  2. 顶级 `main` 方法 `def main(args: Array[String]): Unit = ...` 会像其他方法一样被包装。如果它出现在源文件 `src.scala` 中,可以使用类似 `scala src$package` 的命令从命令行调用它。由于“程序名称”被混淆,建议始终将 `main` 方法放在显式命名的对象中。

  3. `private` 的概念与定义是否被包装无关。`private` 顶级定义始终可以在封闭包中的任何地方访问。

  4. 如果多个顶级定义是具有相同名称的重载变体,则它们必须全部来自同一个源文件。