为什么隐式[ClassTag[T]]解析成功?

use*_*882 3 scala implicit

在下面最简单的示例中,我没有编译错误:

object App {
  def main(args: Array[String]) = {
    test[Int]()
  }
  def test[T <: Int : ClassTag]() = println(implicitly[ClassTag[T]])
}
Run Code Online (Sandbox Code Playgroud)

程序打印Int. ClassTag[T]但我不明白为什么可以找到类型的对象来implicitly[ClassTag[T]]调用?我所做的唯一一件事就是提供泛型类型参数。它从哪里来ClassTag[Int]?

ste*_*ino 5

该:符号定义了上下文绑定,这意味着编译器必须在其隐式作用域中拥有一个实例ClassTag[T]。它是以下内容的语法糖:

def test[T <: Int]()(implicit $ev: ClassTag[T]) = println(implicitly[ClassTag[T]])
Run Code Online (Sandbox Code Playgroud)

implicitly然后,对的调用将$ev作为所需的实例。

但这当然把问题推得更远了:($ev证据)从哪里来?引用Scala 文档(参考TypeTag,但同样适用于ClassTag):

给定上下文绑定 [T: TypeTag],编译器将简单地生成 TypeTag[T] 类型的隐式参数,并将重写该方法,使其类似于上一节中带有隐式参数的示例。