考虑这个简单的例子:
trait Optimizer[+FParam, FRes] {
def optimize(
fn: (FParam) => FRes,
guesses: Seq[FParam] // <--- error
)
}
它不会编译,因为
协变类型
FParam
出现在Seq[FParam]
值猜测类型中的逆变位置。
但是 seq 被定义为trait Seq[+A]
,那么这个逆变的来源是什么?(问题一)
相反,考虑这个简单的例子-FParam
:
trait Optimizer[-FParam, FRes] {
def optimize(
fn: (FParam) => FRes, // <--- error
guesses: Seq[FParam]
)
}
逆变类型出现在类型中的协变位置
(FParam) => FRes
同样的悖论:在 中Function1[-T1, R]
,第一个类型参数显然是逆变的,那么为什么FParam
处于协变位置呢?(问题2)
我可以通过翻转Lower type bounds中描述的方差来解决这个问题,但是为什么它是必要的还不清楚。
trait Optimizer[+FParam, FRes] {
type U <: FParam
def optimize(
fn: (FParam) => FRes,
guesses: Seq[U]
)
}