slo*_*ouc 7 types scala implicit-typing implicits
说我有一个像这样的简单类
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
Run Code Online (Sandbox Code Playgroud)
当声明VAL f2,编译器能够推断出的功能隐式参数的类型f是Int因为该类型是相同的结果类型,和结果类型需要匹配的值的类型f2,这是Int.
然而,投入Ordering[A]混合:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
Run Code Online (Sandbox Code Playgroud)
导致此编译错误:
不明确的隐含值:对象的类型为StringCanBuildFrom,类型=> scala.collection.generic.CanBuildFrom [String,Char,String]的对象Predef和方法$ conforms对象Predef的类型为[A] => <:<[A,A]匹配预期类型A.
如果我在调用时添加类型信息f(),它会编译:
val f2: Int = f[Int]()
Run Code Online (Sandbox Code Playgroud)
首先我遇到了隐式排序的情况,我认为它与Scala从左到右推断有关; 我认为它首先不能匹配返回类型然后推断(隐式)参数类型f.但后来我尝试了没有隐式排序的情况,看到它有效 - 它推断f必须参数化,Int因为返回类型必须是Int(因为f2是Int).
请注意,如果我们删除implicit a: A并仅保留Ordering隐式参数,则错误仍然存在,但变为
在对象排序中从方法Tuple9开始,为类型排序[A]分散隐式扩展.
再次,添加类型参数,以便它变得有val f2: Int = f[Int]()帮助.
这是怎么回事?为什么编译器可以推断出参数A必须是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()
}
Run Code Online (Sandbox Code Playgroud)