首页 > 解决方案 > 当泛型类型与无界通配符一起使用时,不考虑类型参数绑定

问题描述

在我的项目中,我有一个这样的星座:

trait F

trait X[A <: F]

def test(x: X[_]): X[_ <: F] = x

TraitX有一个类型参数,其上限为F. 据我了解,类型X[_]应该X[_ <: F]是等价的。但是scalac2.12.5 抱怨一个不能分配给另一个。

$ scalac -Xscript test test.scala 
test.scala:5: error: type mismatch;
 found   : this.X[_$1] where type _$1
 required: this.X[_ <: this.F]
def test(x: X[_]): X[_ <: F] = x
                               ^

我想不出这个任务会使一个健全的程序变得不健全的情况。这个任务被拒绝的原因是什么?有没有办法允许这样的分配(也许在一个更复杂的例子中)是有问题的?

标签: scalagenericsexistential-typebounded-wildcard

解决方案


这个赋值并没有真正的问题,编译器甚至知道这一点,因为下面的实现编译没有问题:

trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x match { case q: X[t] => q }

如果您允许类型检查器为类型变量推断更精确的界限,从而给类型检查器一些松懈t,它最终会确定t必须是 的子类型F,然后允许您返回值q(与 相同x)而不会抱怨。由于某些可能与 Java 通配符互操作性有关的违反直觉的原因,默认情况下它不会这样做。

(再次取消删除;我最初的猜测似乎并不太遥远,鉴于 Dmytro Mitin 的链接,相比之下,它甚至看起来都没有那么模糊。)


推荐阅读