Scala 类型推断和多参数列表
Scala type inference and multiple arguments list
(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)
,错误就会消失。
为什么多个参数列表的存在会混淆类型检查器?这是错误还是预期结果?
这不是错误 - 参数列表的分离意味着类型参数是根据 第一个 参数列表单独推断的:
f1(123)(ord)
可以改写为:
val partiallyApplied = f1(123)
partiallyApplied(ord)
现在 - partiallyApplied
的类型是什么?由于未显式设置类型参数,并且没有参数 / return 类型可用于推理,因此类型参数被推断为 A
(还没有具体的 B
!所以partiallyApplied
的类型是 (Ordering[A]) => Int
),因此稍后将其与 Ordering[B]
一起使用会给出异常。
相比之下,调用时:
f2(123, ord)
由于ord
的类型为Ordering[B]
,可以推断类型参数为B
,因此编译成功。
(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)
,错误就会消失。
为什么多个参数列表的存在会混淆类型检查器?这是错误还是预期结果?
这不是错误 - 参数列表的分离意味着类型参数是根据 第一个 参数列表单独推断的:
f1(123)(ord)
可以改写为:
val partiallyApplied = f1(123)
partiallyApplied(ord)
现在 - partiallyApplied
的类型是什么?由于未显式设置类型参数,并且没有参数 / return 类型可用于推理,因此类型参数被推断为 A
(还没有具体的 B
!所以partiallyApplied
的类型是 (Ordering[A]) => Int
),因此稍后将其与 Ordering[B]
一起使用会给出异常。
相比之下,调用时:
f2(123, ord)
由于ord
的类型为Ordering[B]
,可以推断类型参数为B
,因此编译成功。