类型中的通配符参数
类型中通配符参数的语法正在从 _ 更改为 ?。示例
List[?]
Map[? <: AnyRef, ? >: Null]
动机
我们希望使用下划线语法 _ 来表示匿名类型参数,使其与值参数列表中的含义保持一致。因此,就像 f(_) 是 lambda x => f(x) 的简写一样,将来 C[_] 将是类型 lambda [X] =>> C[X] 的简写。这将使高阶类型更容易使用。它还将消除这样一个缺陷:用作类型参数时,F[_] 表示 F 是类型构造器,而用作类型时,F[_] 表示它是一个通配符(即存在)类型。将来,无论在何处使用,F[_] 都将表示相同的事物。
我们选择 ? 作为通配符类型的替换语法,因为它与 Java 语法 保持一致。
迁移策略
迁移到新方案很复杂,特别是由于 kind projector 编译器插件仍使用反向约定,其中 ? 表示通配符而不是占位符。幸运的是,kind projector 已将 * 添加为 ? 的替代语法。
通过以下措施,可以逐步迁移
- 在早期版本的 Scala 3 中,
_和?都是通配符的合法名称。 - 在 Scala 3.4 中,
_将被弃用,取而代之的是?作为通配符的名称。提供了一个-rewrite选项,用于将一个重写为另一个。 - 在未来的某个时候,
_的含义将从通配符更改为类型参数的占位符。 - 在
-source future设置下,一些弃用警告已经可用。
为了平滑使用 kind-projector 的代码库的过渡,我们在命令行选项 -Ykind-projector 下采取以下措施
- 在 Scala 3.0 中,
*可用作类型参数占位符。 - 在 Scala 3.2 中,
*已被弃用,取而代之的是_。提供了一个-rewrite选项,用于将一个重写为另一个。 - 在 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 及更高版本)一起使用