在 GitHub 上编辑此页面

类型中的通配符参数

类型中通配符参数的语法正在从 _ 更改为 ?。示例

List[?]
Map[? <: AnyRef, ? >: Null]

动机

我们希望使用下划线语法 _ 来表示匿名类型参数,使其与值参数列表中的含义保持一致。因此,就像 f(_) 是 lambda x => f(x) 的简写一样,将来 C[_] 将是类型 lambda [X] =>> C[X] 的简写。这将使高阶类型更容易使用。它还将消除这样一个缺陷:用作类型参数时,F[_] 表示 F 是类型构造器,而用作类型时,F[_] 表示它是一个通配符(即存在)类型。将来,无论在何处使用,F[_] 都将表示相同的事物。

我们选择 ? 作为通配符类型的替换语法,因为它与 Java 语法 保持一致。

迁移策略

迁移到新方案很复杂,特别是由于 kind projector 编译器插件仍使用反向约定,其中 ? 表示通配符而不是占位符。幸运的是,kind projector 已将 * 添加为 ? 的替代语法。

通过以下措施,可以逐步迁移

  1. 在早期版本的 Scala 3 中,_? 都是通配符的合法名称。
  2. 在 Scala 3.4 中,_ 将被弃用,取而代之的是 ? 作为通配符的名称。提供了一个 -rewrite 选项,用于将一个重写为另一个。
  3. 在未来的某个时候,_ 的含义将从通配符更改为类型参数的占位符。
  4. -source future 设置下,一些弃用警告已经可用。

为了平滑使用 kind-projector 的代码库的过渡,我们在命令行选项 -Ykind-projector 下采取以下措施

  1. 在 Scala 3.0 中,* 可用作类型参数占位符。
  2. 在 Scala 3.2 中,* 已被弃用,取而代之的是 _。提供了一个 -rewrite 选项,用于将一个重写为另一个。
  3. 在 Scala 3.3 中,* 再次被移除,所有类型参数占位符都将用 _ 表示。

这些规则使得在使用 kind projector 插件的 Scala 2 和使用编译器选项 -Ykind-projector 的 Scala 3.0 - 3.2 之间进行交叉构建成为可能。

对于希望一次性过渡到将 _ 作为类型参数占位符的语法的用户,还有一种迁移路径。使用选项 -Ykind-projector:underscores,Scala 3 将 _ 视为类型参数占位符,将 ? 作为通配符的唯一语法。

要使用旧的 Scala 2 源代码进行交叉编译,同时使用 _ 作为占位符,你必须将选项 -Xsource:3 -P:kind-projector:underscore-placeholders 与最新版本的 kind-projector(0.13 及更高版本)和最新版本的 Scala 2(2.13.5 及更高版本和 2.12.14 及更高版本)一起使用