user3663882 user3663882 - 4 months ago 35
Scala Question

Why does implicitly[ClassTag[T]] resolve succesfully?

In the following simplest example I have no compile errors:

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


the program prints
Int
. But I don't understand why an object of type
ClassTag[T]
can be found for
implicitly[ClassTag[T]]
invocation? the only thing I did was to provide generic type argument. Where does the
ClassTag[Int]
come from?

Answer

The : symbol defines a context bound, which means that the compiler has to have an instance of ClassTag[T] in its implicit scope. It's syntactic sugar for the following:

def test[T <: Int]()(implicit $ev: ClassTag[T]) = println(implicitly[ClassTag[T]])

The call to implicitly will then take $ev as the required instance.

But this of course pushes the question a little bit further: where does the $ev (evidence) come from? To quote the Scala documentation (referring to TypeTag, but the same applies to ClassTag):

Given context bound [T: TypeTag], the compiler will simply generate an implicit parameter of type TypeTag[T] and will rewrite the method to look like the example with the implicit parameter in the previous section.