(Scala 2.11.8)
请考虑以下代码:
trait Class[A] {
def f1[B >: A](arg1: Int)(ord: Ordering[B]): Int
def f2[B >: A](arg1: Int, ord: Ordering[B]): Int
def f[B >: A](ord: Ordering[B]): Int = {
f1(123)(ord) // Compilation error!
f2(123, ord) // OK
}
}
此处,行f1(123)(ord)
会引发type mismatch; found : Ordering[B] required: Ordering[A] Note: B >: A, but trait Ordering is invariant in type T. You may wish to investigate a wildcard type such as _ >: A. (SLS 3.2.10)
如果我们将呼叫更改为f1[B](123)(ord)
,则错误消失。
为什么多个参数列表的存在会混淆typechecker?这是一个错误,还是一个预期的结果?
答案 0 :(得分:4)
这不是错误 - 分离到参数列表意味着仅根据第一个参数列表推断出类型参数:
f1(123)(ord)
可以改写为:
val partiallyApplied = f1(123)
partiallyApplied(ord)
现在 - partiallyApplied
的类型是什么?由于类型参数未被明确设置,并且没有用于推理的参数/返回类型,因此类型参数被推断为A
(没有具体的{{} 1}}!所以B
的类型是partiallyApplied
),因此在(Ordering[A]) => Int
之后使用它会产生异常。
相反,在致电时:
Ordering[B]
由于f2(123, ord)
的类型为ord
,因此可以将类型参数推断为Ordering[B]
,因此编译成功。