76

I'm relatively new to Scala and am trying to define a generic object method. However, when I refer to the parameterized type within the method I am getting "No ClassTag available for T". Here is a contrived example that illustrates the problem.

scala> def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
<console>:7: error: No ClassTag available for T
       def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
                                                                        ^

Thanks in advance for help in understanding what is wrong here and how to make this contrived example work.

Freewind
  • 177,284
  • 143
  • 381
  • 649
Chuck
  • 1,788
  • 2
  • 15
  • 28

1 Answers1

92

To instantiate an array in a generic context (instantiating an array of T where T is a type parameter), Scala needs to have information at runtime about T, in the form of an implicit value of type ClassTag[T]. Concretely, you need the caller of your method to (implicitly) pass this ClassTag value, which can conveniently be done using a context bound:

def foo[T:ClassTag](count: Int, value: T): Array[T] = Array.fill[T](count)(value)

For a (thorough) description of this situation, see this document:

https://docs.scala-lang.org/sips/scala-2-8-arrays.html

(To put it shortly, ClassTags are the reworked implementation of ClassManifests, so the rationale remains)

Namefie
  • 107
  • 1
  • 2
  • 13
Régis Jean-Gilles
  • 31,374
  • 4
  • 75
  • 92
  • 13
    Fascinating. With 'import scala.reflect.ClassTag' this works. Thanks. – Chuck Jun 04 '13 at 15:30
  • 3
    People may find this instructive as well - http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html - since ClassManifests are going away. – Chuck Jun 04 '13 at 15:44
  • If we do any comparison of two values of type T in the function body, we need an `implicit` orderer parameter in additional to the `ClassTag` annotation. – AlvaPan Mar 21 '16 at 08:57
  • I found this Java-oriented question helpful as well to understand why we don't need ClassTags for e.g. Lists, but Martin's SIP also hinted at this: http://stackoverflow.com/questions/1817524/generic-arrays-in-java – bbarker Apr 07 '16 at 23:11