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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With