说我有一个像这样的简单类(class)
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
声明 val 时
f2
, 编译器能够推断出函数 f
的隐式参数的类型是 Int
因为那个类型和结果类型是一样的,结果类型需要匹配值的类型f2
, 即 Int
.然而,抛出一个
Ordering[A]
混合:def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
导致此编译错误:
Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A
如果我在调用
f()
时添加类型信息,它编译:val f2: Int = f[Int]()
首先,我遇到了隐式排序的情况,我认为这与 Scala 从左到右推断有关;我认为它无法先匹配返回类型,然后推断
f
的(隐式)参数类型.但是后来我在没有隐式排序的情况下尝试了这个案例,发现它有效 - 它推断出 f
必须由 Int
参数化因为返回类型必须是 Int
(因为 f2
是 Int
)。请注意,如果我们删除
implicit a: A
并只留下 Ordering 隐式参数,错误仍然存在,但变为Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.
再次添加类型参数,使其成为
val f2: Int = f[Int]()
有帮助。这是怎么回事?为什么编译器可以推断出该参数
A
必须是 Int
,但不是那个参数 Ordering[A]
必须是 Ordering[Int]
?
最佳答案
生成排序实例的方式一定有问题,因为下面的代码有效。我会报告一个错误。
case object types {
implicit def buh[X]: List[X] = List()
}
abstract class Foo {
import types._
def f[A]()(implicit l: List[A]): A
val f2: Int = f()
}
关于scala - 从返回类型推断泛型隐式参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36388954/