给出以下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)}
我从消息中不清楚如何纠正这个问题?
答案 0 :(得分:1)
通常,接受Animal
的函数也接受Cat
,因为Cat
是Animal
的类型。但是,这不会自动应用于参数类型: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
逆变(如编译错误中所述)。