在下限类型中键入不匹配

时间:2017-03-23 16:38:25

标签: scala

给出以下scala代码:

trait A {}

class B[T <: A] {
    def f1(b: B[_ <: T]): Unit = {}
    def f2(b: B[_ <: T]): Unit = { b.f1(this) }
}

我收到此编译错误:

  

发现:B [T]

     

必需:B [_&lt;:_ $ 2]

     

注意:T&gt;:_ $ 2,但B类在T类中是不变的。

     

您可能希望将T定义为-T。 (SLS 4.5)

     

def f2(b:B [_&lt;:T]):单位= {b.f1(this)}

我从消息中不清楚如何纠正这个问题?

2 个答案:

答案 0 :(得分:1)

通常,接受Animal的函数也接受Cat,因为CatAnimal的类型。但是,这不会自动应用于参数类型:Array[Cat]不是Array[Animal]的类型,因为您无法将Dog放入Array[Cat]

在您的代码中,您尝试调用函数f1,期望B[_ <: C <: T],(C是传入T的b的f2 )但给它一个B[T]。仅当B[Animal]B[Cat]的类型时才允许这样做 - 例如,如果B[T]表示您可以将类型T写入数组(接受的数组) Animal也接受Cat),但数组也可能包含其他数据类型。

如果您将B[T <: A]更改为B[-T <: A],则会将T标记为逆变类型,这意味着B[Animal]B[Cat],因此函数需要B[Cat]也会接受B[Animal],您的代码将会编译。

答案 1 :(得分:0)

如果您希望某些f1的{​​{1}}和f2参数为B[C],则应将其定义为此类(为了清晰起见) ,至少),而不是C <: T

_

但是,这会对您f1[C <: T](b: B[C]): Unit = {} f2[C <: T](b: B[C]): Unit = ??? 的定义造成问题,因为很明显f2必须为某些b.f1采用B[D]类型的参数,而D <: C的类型为this,因此不会进行类型检查。

为什么不进行类型检查?由于B[T]不会对某些B[T]扩展B[D] ...,除非您使D <: C逆变(如编译错误中所述)。