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?
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.