传递和使用隐式函数而不定义它

passing & using an implicit function without defining it

我没有在任何地方定义函数 ev。那么,下面的代码是如何工作的呢?隐式是否必须在范围内的某处定义才能使用?

def same[T, U](x: U)(implicit ev: U => T): T = {ev(x)}
same(2) // 2

任何时候你有这样的问题,一个好的开始是在 REPL 中使用 Scala 反射 API 来询问编译器发生了什么:

scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}

scala> def same[T, U](x: U)(implicit ev: U => T): T = ev(x)
same: [T, U](x: U)(implicit ev: U => T)T

scala> showCode(reify(same(2)).tree)
res0: String = $read.same(2)(Predef.$conforms)

因此 evPredef.$conforms, an implicit method that will give you an instance of A <:< A for any A, where <:< 扩展 Function1.

提供

这就是一条线索。弄清楚其余部分需要稍微考虑一下类型推断。当您调用 same(2) 时,编译器发现表达式 2 的类型为 Int,并推断出 UInt。接下来它需要弄清楚 T 是什么,为此它会为某些类型 x.

寻找从 Intx 的隐式函数

这就是 $conforms 的用武之地。它是范围内唯一的此类方法,因此编译器选择了它,这意味着 ev 的类型为 Int => IntT 必须是 Int,你就完成了。