代码:
object Test {
import scala.language.implicitConversions
case class C1() {}
case class C2() {}
implicit def c1ToC2(in: C1): C2 = C2()
def from[A, B](in: A)(implicit f: A => B): B = f(in)
def fails(): Future[C2] = {
val future: Future[C1] = Future.successful(C1())
future.map(from) // this line fails to compile!
}
def compiles1(): Future[C2] = {
val future: Future[C1] = Future.successful(C1())
future.map(x => from(x))
}
def compiles2(): Future[C2] = {
val future: Future[C1] = Future.successful(C1())
future.map(from[C1, C2])
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,只有该fails方法无法编译.错误消息是:
错误:(23,16)A => B. future.map(from)没有可用的隐式视图
我很困惑为什么没有发现隐式视图.基于该compiles1和compiles2方法,其中两个编译成功,似乎还有是得自A => B.一个隐含的视图
这里发生了什么,为什么这两种compilesN方法有效,但fails不是?
我的背景:我还在学习Scala,所以很容易就会发现我错过了很明显的东西.:)
我在使用Scala 2.11.8.
编译器尝试在eta扩展from到函数之前解析implicits ,因此from当您调用它时,类型参数尚未推断:
future.map(from)
Run Code Online (Sandbox Code Playgroud)
compiles2显然有效,因为您自己提供类型参数.当你调用时future.map(from[C1, C2]),编译器知道它需要一个隐式的C1 => C2,因为这就是你所说的.
随着compiles1,不同的是多了几分微妙的,但它的事实,茎future.map(from)和future.map(x => from(x))实际上是非常不同的事情.前者使用eta扩展,由于上述原因而失败.有future.map(x => from(x)),没有发生eta扩张.相反,你有一个匿名函数,只需调用 from而不是eta扩展它.因此,编译器可以推断出类型x,它告诉我们x是一个C1(在这种情况下),它可以找到c1ToC2满足方法from的隐式和最终返回类型的类型参数的隐式转换,Future[C2].
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |