Ale*_*rov 3 scala type-inference typechecking
(斯卡拉 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
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,线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),错误就会消失。
为什么多个参数列表的存在会混淆类型检查器?这是一个错误,还是预期的结果?
这不是错误 - 参数列表的分离意味着仅根据第一个参数列表推断类型参数:
f1(123)(ord)
Run Code Online (Sandbox Code Playgroud)
可以改写为:
val partiallyApplied = f1(123)
partiallyApplied(ord)
Run Code Online (Sandbox Code Playgroud)
现在 - 什么是partiallyApplied类型?由于类型参数没有显式设置,并且没有用于推理的参数/返回类型,类型参数被推断为A(还没有具体的B!所以partiallyApplied的类型是(Ordering[A]) => Int),因此使用它Ordering[B]later 给出异常.
相反,在调用时:
f2(123, ord)
Run Code Online (Sandbox Code Playgroud)
由于ord有 type Ordering[B],可以推断出类型参数为B,因此编译成功。